The $6000 Yelp XSS Chain: How Cookie Smuggling Turned a Simple Reflection into Full Account Takeover

The $6000 Yelp XSS Chain: How Cookie Smuggling Turned a Simple Reflection into Full Account Takeover

December 22, 2025 6 min read

A deep, beginner-to-advanced breakdown of a high-impact XSS vulnerability on Yelp where cookie smuggling, unsafe reflection, and logic flaws chained together to enable credential theft and full account takeover.




Disclaimer

This write-up is provided strictly for educational and defensive purposes.
All vulnerabilities discussed were responsibly disclosed and have since been fixed.
Do not attempt to exploit systems you do not own or have explicit authorization to test.


Introduction

Some vulnerabilities look small on the surface. A reflected input here, a strange cookie behavior there. On their own, they might feel like “low severity” findings. But as every experienced security researcher eventually learns, impact is rarely about a single bug. It’s about how small mistakes interact.

This Yelp vulnerability is a perfect example.

What started as an unescaped cookie reflection escalated into a persistent cross-site scripting (XSS) chain, credential harvesting on the business login portal, and full account takeover through third-party authentication flows. The final bounty: $6000.

In this blog, we’ll break the entire chain down step by step, starting from fundamentals so beginners can follow, and going deep enough that experienced engineers and hunters can appreciate the nuance.


XSS Refresher: Why This Class of Bugs Still Matters

Cross-Site Scripting (XSS) allows an attacker to execute JavaScript in another user’s browser within the target site’s origin. That origin-level execution is what makes XSS so dangerous.

At a high level, XSS can lead to:

  • Session hijacking
  • Credential theft
  • Account takeover (ATO)
  • UI manipulation and phishing
  • Abuse of authenticated APIs

There are three main types:

  • Reflected XSS - Input reflected immediately in a response
  • Stored XSS - Payload stored server-side and served later
  • DOM-based XSS - Client-side execution via unsafe DOM handling

In this Yelp case, the vulnerability started as reflected XSS, but clever chaining made it behave like a persistent stored XSS.


The root of the vulnerability was simple but dangerous.

Yelp was embedding the value of a cookie named guvo directly into JavaScript objects rendered on pages such as:

  • https://www.yelp.com
  • https://biz.yelp.com/login

The value was not properly escaped before being injected into the page.

This meant that if an attacker could control the value of guvo, they could inject executable JavaScript into the page context.

Conceptually, the problem looked like this:

  • Server reads guvo cookie
  • Server injects it into inline JavaScript
  • Browser executes whatever is inside

On its own, this is already serious. But the real question was:

How does an attacker control the guvo cookie for another user?


Yelp exposed a query parameter named canary.

When a user visited a URL like:

GET /?canary=test HTTP/1.1
Host: www.yelp.com
HTTP

The server responded with a Set-Cookie header, setting a cookie similar to:

Set-Cookie: yelpmainpaastacanary=test; Domain=.yelp.com; Path=/; Secure; SameSite=Lax
HTTP

This appeared to be a diagnostic or feature-flag mechanism.

By itself, this wasn’t a vulnerability. But it gave attackers something powerful:

A way to plant a cookie in a victim’s browser just by getting them to click a link.

At this point, attackers still couldn’t directly set guvo. That’s where the next flaw came in.


HTTP cookies are supposed to be parsed using semicolons (;) as delimiters:

Cookie: a=1; b=2;
HTTP

Yelp’s backend, however, was incorrectly splitting cookies on spaces.

This meant that a cookie value like:

Cookie: a=1 b=2;
HTTP

was interpreted as two separate cookies.

This parsing flaw enabled cookie smuggling.

Diagram illustrating incorrect cookie parsing where a single space-separated cookie value is split into multiple distinct cookies by the browser.


Here’s where the chain becomes elegant.

The attacker crafted a URL like this:

https://www.yelp.com/?canary=asdf guvo=</script><script>alert(1)</script>
Plain text

The server set a single cookie:

Set-Cookie: yelpmainpaastacanary=asdf guvo=</script><script>alert(1)</script>;
HTTP

But when Yelp later parsed the Cookie header, it split on spaces and treated this as:

  • yelpmainpaastacanary=asdf
  • guvo=</script><script>alert(1)</script>

At this point:

  • The attacker successfully injected a controlled guvo cookie
  • The value was reflected unescaped
  • JavaScript executed in the Yelp origin

XSS achieved.


From Reflected to Persistent XSS

This wasn’t a one-time execution.

Because cookies persist:

  • Victim clicks the link once
  • Malicious cookie is stored
  • Payload executes on every affected page visit

That’s what turned a reflected issue into persistent XSS behavior.

This persistence dramatically increased impact.

Flow diagram showing the persistent XSS attack chain: a victim clicks a link, a malicious cookie is set, and the XSS executes repeatedly across subsequent sessions.


Proof of Concept #1: Keylogging on Business Login

The Yelp business portal (biz.yelp.com/login) contains sensitive login forms.

With XSS execution on that page, the attacker injected JavaScript that:

  • Waited for the page to load
  • Hooked email and password input fields
  • Listened for typing and submission
  • Exfiltrated credentials to an attacker-controlled endpoint

Because the script executed inside Yelp’s origin, browser security controls did not block it.

This enabled real-time credential theft.


Proof of Concept #2: Account Takeover via Google Linking

Yelp supports Google account linking.

The flow involved:

  • CSRF tokens embedded in pages
  • A POST request linking a Google id_token to a Yelp account

Using XSS, the attacker:

  1. Fetched a page containing the CSRF token
  2. Extracted the token via JavaScript
  3. Submitted a forged request linking the attacker’s Google account to the victim’s Yelp account

Once linked, the attacker could log in as the victim using Google Sign-In.

This was a full account takeover.

Illustration depicting the account takeover process where an XSS payload extracts a CSRF token and links the victim's account to a third-party OAuth provider.


Why This Bug Was High Severity

This vulnerability:

  • Required only a click
  • Persisted across sessions
  • Allowed credential theft
  • Enabled account takeover
  • Affected both consumer and business accounts

That combination justified the $6000 bounty.


Defensive Lessons for Engineers

1. Never Reflect Untrusted Input into Executable Contexts

Cookies, headers, query parameters - all are attacker-controlled.

Always escape based on context.


2. Follow Standards When Parsing Protocols

Cookie parsing bugs are subtle and dangerous.

If you re-implement protocol parsing, you will almost certainly get it wrong.


3. Assume Features Will Be Chained

The canary parameter wasn’t dangerous by itself.

Neither was cookie reflection alone.

Security failures compound.


4. CSP Is Not Optional

A strict Content Security Policy could have prevented inline script execution even after reflection.

Defense-in-depth matters.


Hunting Takeaways for Researchers

  • Look for non-obvious input sources like cookies
  • Test how servers parse edge cases
  • Chain low-impact issues creatively
  • Think like a system, not a scanner

Conclusion

This Yelp vulnerability wasn’t about a single clever payload. It was about curiosity, protocol knowledge, and chaining behavior that developers didn’t expect.

That’s what real-world web security looks like.

Small assumptions. Big consequences.


References

  • OWASP Cross-Site Scripting Prevention Cheat Sheet
  • RFC 6265 - HTTP State Management Mechanism
  • PortSwigger Web Security Academy - XSS
  • Publicly disclosed HackerOne reports (Yelp)

Join the Security Intel.

Get weekly VAPT techniques, ethical hacking tools, and zero-day analysis delivered to your inbox.

Weekly Updates No Spam
Herish Chaniyara

Herish Chaniyara

Web Application Penetration Tester (VAPT) & Security Researcher. A Gold Microsoft Student Ambassador and PortSwigger Hall of Fame (#59) member dedicated to securing the web.

Read Next

View all posts

For any queries or professional discussions: herish.chaniyara@gmail.com