Description
Can you find the flag? It is hidden in the HTML source of this page.
Solution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1View the page source
ObservationThe description says the flag is hidden in the page's HTML source. That means the password check runs in the browser rather than on a server, so the raw source is the place to look.Open the challenge URL. Press Ctrl+U (or right-click > View Page Source) to see the raw HTML. Look for a script tag containing the password validation logic.What didn't work first
Tried: Opening the Elements panel in DevTools instead of View Page Source.
The Elements panel shows the live DOM after JavaScript has run, not the raw HTML the server sent. View Page Source (Ctrl+U) shows the file exactly as downloaded, including the original script tags you need to read.
Tried: Searching for the flag text directly in the source with Ctrl+F for 'picoCTF'.
The flag is never written out as a single string. It is assembled from parts inside the JavaScript validation logic, so you have to read the script and rebuild it from the substring comparisons.
Learn more
When a web application validates a password purely in client-side JavaScript, the correct password must exist somewhere in the code the browser downloads. There is no server-side check to hide the secret.
Step 2Find and concatenate the flag parts
ObservationThe script checks your input in slices, using a series of .substring() calls against hardcoded strings. Each slice is one piece of the flag, so putting the pieces back in position order rebuilds it.The JavaScript validation function splits the input into 4-character chunks using .substring() and compares each chunk to a hardcoded value. Find each expected value in the source code and concatenate them in positional order to form the complete flag.What didn't work first
Tried: Typing random guesses into the password form and watching the JavaScript alert to confirm.
The validation logic is fully visible in the source, so there is nothing to guess at. Reading the substring comparisons hands you the exact expected value for every position.
Tried: Concatenating the hardcoded strings in the order they appear in the source file rather than by their positional arguments.
The substring() calls do not always appear in start-index order. Each one names its own start and end index, so sort the expected values by start index before joining them. Source order can produce a garbled flag.
Learn more
Look for lines like:
checkpass.substring(0, split) == 'pico',checkpass.substring(split, split*2) == 'CTF{', etc. The variablesplitis typically 4, so each check covers a 4-character slice. Concatenate all the expected values in order of their start position.This challenge is the easiest demonstration that client-side validation provides zero real security - a user never even needs to type anything into the form; they just read the source.
Interactive tools
- Strings ExtractorPull printable text from any binary, library, or image. ASCII and UTF-16 detection, configurable minimum length, flag-like highlight, no command line needed.
- Regex TesterTest regular expressions against a string with live match highlighting, flag toggles, and common CTF pattern shortcuts.
Flag
Reveal flag
picoCTF{no_clients_plz_...}
The password is validated by substring position checks in the JavaScript source. Concatenate all the expected 4-character substrings in positional order to reconstruct the flag.