picoCTF · picoGym Web Exploitation Easy 50 pts

Bookmarklet — Hardcoded Key in Client-Side JS

OWASP A02 — Cryptographic Failures

Vulnerability Overview

An encrypted flag and its decryption key were both stored in the same client-side JavaScript file. Regardless of the encryption algorithm used, co-locating ciphertext and key in publicly accessible code renders the encryption meaningless.

Discovery and Exploitation

The page source contained a JavaScript bookmarklet in a textarea. Reading it revealed three components: an encrypted flag string, a decryption function implementing a XOR-style cipher, and the decryption key "picoctf" hardcoded in plain text.

Rather than saving the bookmarklet and clicking it, the JavaScript was copied directly into the browser console (F12 → Console) and executed. The decryption function ran and displayed the flag in an alert dialog.

Root Cause

The application attempted to protect the flag with encryption but stored both the ciphertext and the key in publicly readable JavaScript. This is not a cipher implementation flaw — it is a fundamental design error. Encryption is only effective when the key is kept secret.

ControlImplementation
Decrypt server-side onlyThe client should never receive the key or the ability to decrypt — serve the plaintext after server-side authorization
Never co-locate key and ciphertextIf both are accessible to an attacker, the encryption provides zero confidentiality
Key Insight: Encryption is not a client-side operation for protecting server secrets. The moment a decryption key touches the client, the protected data is no longer protected. All decryption of sensitive content must happen on a server the user cannot directly inspect.
Flag See challenge on picoCTF picoGym