# XSS [flow] - on www.paypal.com/paypalme/my/landing (requires user interaction)

Base64 flow param on PayPal.me landing passed javascript: URLs into modal cancel/return hrefs, yielding reflected XSS on click.

- Payout: hidden
- Severity: medium
- Program: PayPal
- Found by: stefanovettorazzi
- Disclosed: 2018-11-06
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/425200
- Library page: https://bugbountylibrary.com/r/h1%3A425200
- Tags: area:web domain:web impact:ato kind:bounty platform:hackerone sev:medium technique:source-review vuln:xss

**Target:** www.paypal.com/paypalme/my/landing flow parameter
**Root cause:** The base64 `flow` parameter decodes to returnUrl/cancelUrl which are placed directly into href attributes of modal buttons; validation only checks the URL starts with `javascripT:paypal.com`-style prefix, which is bypassable via `PAYPAL.com=1,location='...'` since PAYPAL is a defined object.
**Steps:**
1. Visit `https://www.paypal.com/paypalme/my/landing?flow=cmV0dXJuVXJsPWphdmFzY3JpcFQ6UEFZUEFMLmNvbSUzZDEsbG9jYXRpb24lM2QnamF2YXNjcmlwdDpceDNjc3ZnXHgyMG9ubG9hZD1hbGVydFx4Mjhkb2N1bWVudC5kb21haW5ceDI5XHgzZScmY2FuY2VsVXJsPWphdmFzY3JpcFQ6UEFZUEFMLmNvbSUzZDEsbG9jYXRpb24lM2QnamF2YXNjcmlwdDpceDNjc3ZnXHgyMG9ubG9hZD1hbGVydFx4Mjhkb2N1bWVudC5kb21haW5ceDI5XHgzZSc=`
2. Click the X at top right of the modal window
3. Payload decodes to `returnUrl=javascript:PAYPAL.com=1,location='javascript:\x3csvg\x20onload=alert\x28document.domain\x29\x3e'&cancelUrl=...`
**How found:** Noticed the flow param is base64 of returnUrl/cancelUrl, tested javascript: scheme acceptance, found prefix restriction to paypal.com, then realized PAYPAL global object exists so `PAYPAL.com=1` satisfies the prefix while comma allows injecting `location=` assignment; worked around blocked chars via JS hex escapes.
**Exploitation:** Victim clicks the modal close (X) or Done button whose href is the attacker-controlled javascript: URL; the JS executes in paypal.com origin, allowing actions as the authenticated user.
**Insight:** When a URL validator only checks a string prefix like `javascript:paypal.com`, look for a global JS object matching that name (PAYPAL) so you can append `=1,location='...'` and turn the prefix into a valid assignment expression; use JS \xNN escapes to bypass character blocklists.

