picoCTF · picoGym Web Exploitation Easy 50 pts

Don't Use Client-Side — Flag in JS Verification Logic

OWASP A07 — Identification and Authentication Failures

Vulnerability Overview

A password verification function implemented entirely in client-side JavaScript compared user input against the flag in fragments. Despite the scrambled order of substring checks, all components were visible in the public source code.

Exploitation

Viewing page source revealed a verify() function that split the expected password into 8 four-character chunks and compared them in order:

split = 4;
checkpass.substring(0, split)       == 'pico'  // 0
checkpass.substring(split, split*2)  == 'CTF{'  // 1
checkpass.substring(split*2, split*3) == 'no_c' // 2
checkpass.substring(split*3, split*4) == 'lien' // 3
checkpass.substring(split*4, split*5) == 'ts_p' // 4
checkpass.substring(split*5, split*6) == 'lz_2' // 5
checkpass.substring(split*6, split*7) == 'eb02' // 6
checkpass.substring(split*7, split*8) == 'b45}' // 7

Reading them in order: picoCTF{no_clients_plz_2eb02b45}.

Key Insight: Splitting a secret into fragments in JavaScript does not obscure it — every fragment is visible in source. No amount of scrambling, encoding, or variable renaming in client-side code provides meaningful protection because the user controls and can read the execution environment. Verification must happen server-side.
Flag See challenge on picoCTF picoGym