# Solving DOM XSS Puzzles

Two DOM XSS chains: postMessage without origin check leading to eval and session token theft, and CSP bypass via newline open redirect to inject script.

- Payout: Research
- Severity: high
- Program: Company A
- Write-up by: Eugene Lim
- Disclosed: 2022-02-03
- Write-up quality: 8/10
- Original: https://spaceraccoon.dev/solving-dom-xss-puzzles/
- Library page: https://bugbountylibrary.com/r/blog%3Aspaceraccoon-dev-solving-dom-xss-puzzles
- Tags: area:web domain:web impact:ato kind:research platform:research sev:high technique:chained technique:parser-differential technique:source-review vuln:open-redirect vuln:xss

**Target:** Web application postMessage handlers and OAuth confirmation page
**Root cause:** Puzzle A: postMessage handler lacks origin validation, sets window.settingsSync from attacker data, which flows into domain concatenation and eval sink. Puzzle B: unsanitized introduction field injected into page, domain parameter controls request destination, and CSP allows *.googleapis.com plus open redirect with newline bypass.
**Steps:**
1. Puzzle A: Use postmessage-tracker to find handler at abc.cloudfront.net/iframe_chat.html accepting e.data.type=='ChatSettings' without origin check
2. Set window.settingsSync.iframeChatSettings with region='.my.website/malicious.php?_bad' to make domain point to attacker server
3. Host malicious.php returning JSON with config='a;alert()//' and versionNumber='2'
4. Open feedback.companyA.com, send postMessage to iframe to trigger eval sink
5. Chain with parent postMessage handler validating origin abc.cloudfront.net to leak sessionToken via IframeLoaded message
6. Puzzle B: Set domain=storage.googleapis.com/myevilbucket/oauth_data.json%3F to control GET response with introduction=<script>alert()</script>
7. Bypass CSP script-src using open redirect at t.companyb.com/redirect?url=http://evil.com%0A.companyb.com/ to load payload from evil.com
8. Inject script tag with src pointing to open redirect to execute XSS
**How found:** Puzzle A: Used postmessage-tracker Chrome extension to detect postMessage calls, noticed missing origin check, searched for window.settingsSync in Burp to find eval sink. Puzzle B: Noticed OAuth page dynamically fetches data based on domain parameter, tested injection into introduction field, encountered CSP, found *.googleapis.com loophole, used saved open redirect with newline bypass.
**Exploitation:** Puzzle A: Attacker hosts malicious JSON on own domain, sends postMessage to vulnerable iframe, triggers eval XSS, then uses XSS to send IframeLoaded postMessage to parent, which returns credentialConfig containing sessionToken, exfiltrated to attacker. Puzzle B: Attacker controls domain parameter to fetch malicious JSON from Google Cloud Storage bucket, injects script via unsanitized introduction field, bypasses CSP using open redirect with newline to load external script.
**Escalation:** Puzzle A: Chained iframe XSS with parent postMessage handler to steal session token. Puzzle B: Chained open redirect with newline bypass to circumvent CSP and execute arbitrary script.
**Insight:** When auditing postMessage handlers, trace the data flow from message event to sinks like eval or URL construction; missing origin checks are common. For CSP bypasses, look for allowed domains like *.googleapis.com that permit user-controlled content, and chain with open redirects that have parser differentials (e.g., newline truncation) to load external scripts.
