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 1
Inspect the JavaScriptObservationI noticed the site offered a 'Continue as guest' button and the description mentioned anisAdmincookie, which suggested reading the page source or DevTools to confirm the cookie name and starting value before attempting to tamper 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 structure, not cookie storage or JavaScript source. Cookies are found under the Application tab (Chrome) or Storage tab (Firefox), not in the Elements tree. JavaScript handlers are better read in the Sources panel or by right-clicking 'View Page Source' to see the raw HTML.
Tried: Searching the page source for 'flag' or 'admin' text directly.
The flag is not embedded in the HTML source - it is only returned by the server when the cookie value passes the authorization check. The useful thing to find in the source is the cookie name and what value it is initialized to, 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 2
Toggle the cookieObservationI noticed theisAdmincookie was initialized to 0 by the onclick handler, which suggested the server used a simple truthy check and that flipping the value to 1 would unlock the privileged/check.phpresponse.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.
Without the cookie, the server has no isAdmin signal at all and will likely fall back to treating the request as a guest, returning no flag. The server checks for isAdmin=1 specifically, so the cookie must be present with the value 1, not absent.
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.