ORDER66
umasscybersec
Task: a Flask grid stores one user-controlled value per session in Redis, but only one order slot is rendered unsafely and its index is derived from a leaked PRNG seed. Solution: recover the unsafe slot from the shared seed, store JavaScript there, then send the admin bot to the shared URL so console.log(document.cookie) returns the non-httpOnly flag cookie.
$ ls tags/ techniques/
ORDER66 — UMassCTF 2026
Summary
This challenge is a compact stored XSS bot chain with one extra twist: execution order matters. The title is the hint. There are 66 possible order slots, but only one is rendered with Jinja's |safe, and the application leaks enough state to predict exactly which slot that is.
Once the unsafe slot is known, the rest of the attack is straightforward:
- store
<script>console.log(document.cookie)</script>in the one unsafe box, - send the admin bot to the shared
/view/<uid>/<seed>URL, - let the bot execute the stored XSS,
- steal the
flagcookie because it is explicitly set withhttpOnly: false, - read it back because
/admin/visitreturns Puppeteer's stdout.
Description
Execute Order... wait which one was it?
The page presents a 66-cell grid where only one box may contain data at a time. A share URL is exposed for the current session, and an admin bot can be asked to visit a supplied page.
Source Analysis
Flask application
app.py assigns each visitor a user_id and a numeric seed in the session. The important helper is:
def get_grid_context(uid, seed): random.seed(seed) v_index = random.randint(1, 66) data = {i: (db.get(f"{uid}:box_{i}") or "") for i in range(1, 67)} return data, v_index
So the dangerous slot is not random per render in any strong sense. It is fully determined by the leaked seed.
The main page also leaks a share URL directly in the HTML:
value="http://{{ host }}/view/{{ user_id }}/{{ seed }}"
That is enough to recover both values needed to recompute the vulnerable index locally.
Template sink
templates/index.html is where the bug lives:
{% if i == vuln_index %} {{ content | safe }} {% else %} {{ content }} {% endif %}
...
Permission denied (requires auth)
Sign in to read this free writeup
This writeup is free — just sign in with GitHub to read it.
$ssh [email protected]