Challenge

An AI chatbot web app built with Flask. Normal users can chat; admins get more features.

Approach

  1. Source map leak: The frontend JS has a .map file exposed at /static/app.js.map. It reveals the source, including an API endpoint /api/v0/admin and comments mentioning the JWT secret.
  2. Legacy endpoint: GET /api/v0 with header X-Dev-Mode: 1 returns a JWT signed with the leaked secret.
  3. Forge admin JWT: Use the leaked secret to sign a JWT with {"role": "admin"}.
  4. SSTI: The admin chat endpoint passes user input directly into a Jinja2 render_template_string() call. Send {{config}} to confirm, then:
1
{{''.__class__.__mro__[1].__subclasses__()[439](['cat','/flag.txt'],stdout=-1).communicate()[0].decode()}}

Flag

boroCTF{pub1ic_k3y_g0es_both_ways}