← all writeups
WebHuntress CTF 2026

Double Spent

A two-route app: POST /execute-bdb3f6 spends one credit (read balance → check > 0 → decrement, and that's not atomic), and GET /audit-ad790f hands over the flag once the balance goes negative.

A fresh instance seeds the balance to exactly 1 and never regenerates, so you have to race that single credit before any clean spend consumes it. (My first instance was already spent to 0 — 3,500+ sequential attempts did nothing — so it needed a reset.)

On a fresh instance I fired 50 concurrent spends in a single tick. Five of them read balance == 1 and passed the > 0 check before any decrement committed, driving the balance to −4. Audit flipped from 403 credit_not_overspent to:

{"ok":true,"effect":"single_credit_spent_twice","evidence":"proof_..."}

The X-Arena-Diagnostic-*-Overlap headers were the challenge literally scoring how well my requests overlapped, and the ~1.5 ms handler is exactly why the TOCTOU window is so easy to hit. Textbook double-spend.