# wp-embed XSS on Safari

WordPress wp-embed postMessage handler on Safari treats javascript: URLs as having a host, letting an embedded attacker post redirect top window to javascript: and run XSS.

- Payout: hidden
- Severity: medium
- Program: WordPress
- Found by: zoczus
- Disclosed: 2023-07-01
- Write-up quality: 8/10
- Original: https://hackerone.com/reports/1238528
- Library page: https://bugbountylibrary.com/r/h1%3A1238528
- Tags: area:web domain:web impact:integrity kind:bounty platform:hackerone sev:medium tech:wordpress technique:parser-differential vuln:open-redirect vuln:xss

**Target:** WordPress core wp-embed.js postMessage handler / embed.php
**Root cause:** The link handler validates t.value by creating an anchor and comparing i.host to the iframe src host, but Safari parses javascript://host/%0a... as having a host, so the same-origin check passes for a javascript: URL.
**Steps:**
1. Attacker hosts a WordPress instance and edits wp-includes/theme-compat/embed.php to add a script that reads location.hash secret and calls `window.top.postMessage({secret,message:'link',value:'javascript://'+host+'/%0aalert(document.domain);//'},'*')`.
2. Publish a post on attacker blog and obtain its URL.
3. On victim WordPress site (viewed in Safari), create a post embedding the attacker post.
4. The embed iframe sends the postMessage; handler passes host check and sets `top.location.href` to the javascript: URL, executing alert.
**How found:** Reading the wp-embed postMessage handler, noticed the host comparison via anchor element and tested how Safari parses javascript: URLs with an embedded host, finding it returns a non-empty host unlike other browsers.
**Exploitation:** Attacker needs their blog post embedded on the victim site; the embed iframe (attacker-controlled content) sends a postMessage with message='link' and a javascript: value whose parsed host matches the iframe src host in Safari, causing top-window navigation to javascript: and script execution in victim origin.
**Insight:** When origin/host checks are done by parsing attacker URLs with the browser's own URL parser, test scheme-confusion payloads like `javascript://expected-host/%0a...` per-browser; Safari assigns a host to javascript: URLs, defeating naive host equality checks.
