# DOM Based XSS in www.hackerone.com via PostMessage (bypass of #398054)

Marketo's postMessage origin check used indexOf on the full origin string, so registering app-sj17.ma bypassed it and enabled DOM XSS on www.hackerone.com.

- Payout: hidden
- Severity: low
- Program: HackerOne
- Found by: honoki
- Disclosed: 2019-05-04
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/499030
- Library page: https://bugbountylibrary.com/r/h1%3A499030
- Tags: area:web domain:web impact:integrity kind:bounty platform:hackerone sev:low technique:incomplete-fix vuln:xss

**Target:** Marketo forms2.min.js postMessage handler on www.hackerone.com
**Root cause:** The origin check uses `0 === i.indexOf(a.originalEvent.origin)`, a prefix match against `https://app-sj17.marketo.com/...`, so any origin that is a prefix of that string (e.g. `https://app-sj17.ma`) passes.
**Steps:**
1. Register domain `app-sj17.ma` (prefix of `app-sj17.marketo.com`).
2. Host the original POC from #398054 at `https://app-sj17.ma/marketo/post2.html`.
3. Victim browses to the POC page, which postMessages to the hackerone.com Marketo iframe.
4. The `indexOf` prefix check passes and the malicious redirect/JS executes in www.hackerone.com context.
**How found:** Reviewed the Marketo forms2.min.js postMessage handler and noticed the origin validation used `indexOf(...) === 0` (prefix match) rather than strict equality, then realized a shorter domain like app-sj17.ma is a valid prefix of app-sj17.marketo.com.
**Exploitation:** Attacker hosts a page on a domain whose name is a string prefix of the legitimate Marketo origin, sends a crafted postMessage payload to the embedded Marketo form on www.hackerone.com; the flawed indexOf check accepts it and the parsed JSON triggers a redirect/JS execution in the target origin (limited to browsers without CSP).
**Insight:** When auditing postMessage handlers, treat `indexOf(origin) === 0`, `startsWith`, or regex prefix checks as bypassable: any domain that is a string prefix of the trusted origin (e.g. `trusted.co` vs `trusted.com`) passes. Register the shorter TLD to prove it.

