Description
The site sets an isAdmin cookie to 0 when you continue as guest. Flip it to 1 and reload /check.php to see the flag.
Setup
Click “Continue as guest” to set the cookie or create it manually in DevTools.
Open the browser’s storage view, change isAdmin from 0 to 1.
Refresh /check.php; the server now treats you as admin and prints the flag.
Solution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1Inspect the JavaScript
ObservationThe site offers a continue-as-guest button and the description mentions an isAdmin cookie. Read the page source, or DevTools, to confirm the cookie's name and starting value before tampering with it.The main page shows the onclick handler that createsisAdmin=0, so you know which cookie name to modify.What didn't work first
Tried: Opening the Elements panel in DevTools to find the cookie name.
The Elements panel shows the live DOM, not cookie storage and not JavaScript source. Cookies live under the Application tab in Chrome or Storage in Firefox. Read the handlers in the Sources panel, or from View Page Source.
Tried: Searching the page source for 'flag' or 'admin' text directly.
The flag is not in the HTML source; the server only returns it once the cookie passes the authorization check. What the source gives you is the cookie's name and starting value, so you know what to change.
Learn more
HTTP cookies are small key-value strings that browsers store and automatically send with every request to the matching domain. Servers use them for session management, user preferences, and authentication state. Because cookies live in the browser, users have full read and write access to them via DevTools or JavaScript.
In this challenge, the developer made a classic mistake: trusting a client-controlled value (
isAdmin=0) for an authorization decision. The server should never rely on data from the client alone to determine privilege levels. Any value the client sends can be forged.To inspect cookies in Chrome or Firefox, open DevTools (
F12), go to the Application tab (Chrome) or Storage tab (Firefox), and expand the Cookies section. You can double-click any value to edit it directly.Cookies can also be manipulated via JavaScript in the browser console. Running
document.cookie = "isAdmin=1"creates or overwrites the cookie immediately without needing the Application tab. This technique is useful when the DevTools storage panel is cumbersome or when you need to set multiple cookies quickly during a competition. However, cookies marked with theHttpOnlyflag cannot be accessed this way - they are invisible to JavaScript and must be edited through the DevTools storage panel directly.For command-line-based testing,
curlallows you to specify custom cookies with-b "isAdmin=1"and inspect the full HTTP response without a browser. This is faster for scripted testing and lets you see raw response headers that browsers sometimes obscure. The combination of browser DevTools for initial exploration andcurlfor precise, repeatable requests is a standard web testing workflow.Step 2Toggle the cookie
ObservationThe onclick handler sets isAdmin to 0. That is a simple truthy check on the server, so flipping the value to 1 should unlock the privileged response.Edit the cookie value (or create a newisAdmin=1cookie) and revisit/check.phpto read the flag.What didn't work first
Tried: Typing document.cookie = 'isAdmin=1' in the browser console and then reloading the same index page instead of /check.php.
The cookie change takes effect immediately, but the flag is only returned by /check.php - not the main landing page. After setting the cookie, you must navigate to /check.php (or reload it if already there) to see the server's privileged response.
Tried: Deleting the isAdmin cookie entirely instead of changing its value to 1.
With no cookie at all, the server has no isAdmin signal and falls back to treating you as a guest, so no flag. It checks for the value 1 specifically, which means the cookie has to be present and set, not missing.
Learn more
Cookie tampering is one of the simplest web attack techniques. Because browsers freely expose cookie storage to the user, any client-side authorization check is trivially bypassed. Proper implementations use signed sessions - the server cryptographically signs the session data so any modification is detected.
Secure cookie practices include: setting the
HttpOnlyflag to prevent JavaScript access, theSecureflag to enforce HTTPS-only transmission, andSameSite=Strictto prevent cross-site request forgery. However, none of these prevent a user from modifying their own cookie value in DevTools.The real fix is server-side session validation: store the admin flag in a server-side session keyed by a random, unpredictable session token. The token itself is useless without the server's session data, so tampering with the cookie value achieves nothing.
Many modern frameworks handle this correctly by default. Express.js (Node) uses
express-sessionwith a server-side store; Django stores session data in the database and sends only a signed session key; PHP's built-in sessions write data to the server filesystem. The pattern is always the same: the cookie holds a random identifier, and all sensitive state lives server-side under that key.JWT (JSON Web Tokens) are a related technology that encodes claims (including roles and permissions) directly in the token - but crucially, tokens are signed with a secret key. Any tampering with the payload invalidates the signature, so the server can detect and reject modified tokens. However, JWTs have their own pitfalls: the
alg: noneattack, weak signing keys, and improper signature verification have all been sources of real vulnerabilities. Cookie-based authentication is not inherently weaker than JWTs - both require careful implementation.
Interactive tools
- Flask Session DecoderDecode Flask / itsdangerous session cookies. Splits payload, decompresses zlib, parses JSON, and verifies the HMAC signature when given the secret.
Flag
Reveal flag
picoCTF{gr4d3_A_c00k13_65fd1...}
Cookie tampering is a common beginner attack; always validate privilege server side.