
// TL;DR
A logic bug I found across several sites, including Upwork. Many sites store the referrer in a cookie, and many sit behind a WAF like Cloudflare that blocks requests containing attack-looking strings. Put those together: if you can get a malicious-looking string into the referrer cookie, the user’s own WAF starts blocking them on every subsequent request — a self-inflicted denial of service. By crafting a page whose URL contains an XSS-looking payload and bouncing the victim through it, the site quietly writes that payload into the victim’s referrer cookie, and from then on the WAF locks the victim out of the site. Upwork fixed it and paid a $400 bounty.
The ingredients
This bug comes from two normal, individually-harmless behaviours colliding:
- The site stores the referrer in a cookie. Lots of sites record where a visitor came from by writing the
RefererURL into a cookie. - The site is behind a WAF that blocks malicious strings. A WAF like Cloudflare inspects incoming requests and blocks any that contain attack signatures — an XSS or SQLi-looking string such as
"><script>alert(1)</script>. When that happens, you can’t use the site until the offending input is removed.
Neither is a vulnerability by itself. The problem is what happens when the first feeds the second.
The trick
If the site writes the referrer into a cookie without sanitising it, I can poison that cookie with a WAF-triggering string — and because the cookie is then sent on every future request, the WAF blocks the user from their own account.
The mechanism, step by step:
- An external site (
exsite.com) links/redirects to the target (vulnsite.com). vulnsite.comwrites the referrer — theexsite.comURL — into a cookie.- So I build a page,
exsite.com/page.html, that redirects tovulnsite.com, and I put a malicious payload in its own URL as a query string:
exsite.com/page.html?%22%3E%3Cscript%3Ealert(1)%3C%2Fscript%3E
- When
vulnsite.comloads and records the referrer, it stores that entire URL — payload and all — in the cookie. (The cookie is written after the page loads, so the first visit goes through fine.) - On the next request, the browser sends that poisoned cookie, the WAF sees the attack string inside it, and blocks the user. They can no longer reach the site until they manually clear the cookie — which most users have no idea how to do.
The payload never has to execute. Its mere presence in a cookie the WAF inspects is enough to lock the victim out.
The Upwork case
Upwork showed exactly this pattern. When an external site redirected to Upwork, Upwork set a referrer cookie containing the referring URL. Sending a referrer URL with malicious characters on the end:
https://attacker-page.example/page.html?%22%3E%3Cscript%3Ealert(1)%3C%2Fscript%3E
…caused Upwork to store the cookie with that payload value. On refresh, Cloudflare blocked access to Upwork — and because the cookie had a long expiry, the lockout persisted.
I reported it; Upwork patched it (details in the fix below) and rewarded a $400 bounty. I found the same issue on other sites too — some triaged and rewarded it, and at the time several remained unpatched.

Attack scenario
- The attacker builds the crafted page and hosts it anywhere.
- They send the crafted URL to a victim (a user of the affected site).
- The victim clicks it; the payload is silently written into their referrer cookie for the target site.
- The victim can no longer access the site — their own WAF now blocks them on every request — until they clear the cookie.
It needs no privileges and works across operating systems and browsers, because it abuses the site’s own cookie + WAF behaviour, not anything client-specific.
The fix
The root cause is storing an unsanitised, full referrer URL in a cookie. Two clean fixes:
- Store only the domain (
www.site.com) in the referrer cookie, not the full URL with its query string — so there’s nowhere for a payload to ride along. - Encode the cookie value (for example, base64) so whatever is stored can’t match a WAF attack signature.
Upwork fixed it with option 2, base64-encoding the referrer value.
Takeaways
- Think about data the app stores about you, then sends back. Referrer cookies, user-agent logging, cached headers — anything the app records from the request and replays later is worth testing. The attack surface isn’t only what’s displayed; it’s what’s stored and re-sent.
- A WAF can be turned against its own user. Signature-based blocking assumes the attack comes from the attacker. If you can plant the signature in something the victim sends every request (a cookie), the WAF becomes the denial-of-service tool.
- “Harmless” behaviours combine into real bugs. Storing a referrer is fine. Running a WAF is good. Together, without sanitisation, they’re a persistent client-side DoS. Logic bugs live in these intersections — which scanners miss.
- Think like a bad guy, and try the uncommon path. This one came from doing something deliberately weird rather than running a tool. Use your head, not just a scanner.
Thanks for reading — hope it was useful. Happy hacking!
Leave a Reply