Hacker Holidays Day 8: Towel on the Sunbed
A crypto rewards app lets guests claim a daily reward once every 24 hours. The
catch is a gap between when the claim hits the server and when it records that the
reward was claimed. Wide enough to walk a whale through, as the brief put it. The
goal is Whale tier and the vault behind it, via a race condition on /claim.
Setting up the race
A single claim succeeds once. Repeating it returns:
HTTP/1.1 429 Too Many Requests
{"error":"Reward already claimed. Please wait before claiming again."}
So the cooldown is enforced. The question is whether it is enforced atomically. I
sent /claim to Burp Repeater and duplicated it into 10 tabs. This has to run
against a fresh session that has never claimed, since an account already on
cooldown just returns 429 on every parallel attempt.
Then I used Burp’s “Send group (parallel)” to fire all 10 at once. If the server
checks “has this user claimed today?” and then writes “claimed = true” as two
steps, sending many requests at once slips several through the check before any
finish the write. Responses came back as a mix of 429 and one genuine 200 OK:
Spoiler: the winning race response
{"message":"Staking reward claimed successfully.","reward":50,"tier":"Whale"}
That one win bumped the tier to Whale. With the dashboard refreshed, Whale tier unlocked the vault, and “Open Vault” revealed the flag. Redacted here.