# $8,000 Bug Bounty Highlight: XSS to RCE in the Opera Browser

DOM XSS via drag-and-drop innerHTML in Opera's My Flow page chained to a privileged extension's SEND_FILE/OPEN_FILE APIs to write and execute a .bat file.

- Payout: $8,000
- Severity: high
- Program: Opera
- Credited: Renwa
- Disclosed: 2021-09-24
- Write-up quality: 8/10
- Original: https://blogs.opera.com/security/2021/09/8000-bug-bounty-highlight-xss-to-rce-in-the-opera-browser
- Library page: https://bugbountylibrary.com/r/blog%3Ablogs-opera-com-security-2021-09-8000-bug-bounty-highlight-xss-to-rce-in-the-opera-browser
- Tags: domain:browser impact:integrity impact:rce kind:bounty platform:blog sev:high tech:chromium technique:chained vuln:rce vuln:xss

**Target:** web.flow.opera.com My Flow page and Opera Touch Background component extension
**Root cause:** The drag-and-drop handler takes attacker-controlled dataTransfer 'text/html', regex-extracts an img src, and assigns it to innerHTML of a detached span; img onerror fires even when not rendered. The hidden extension exposes SEND_FILE (arbitrary write to Downloads/MyFlow) and OPEN_FILE (opens any file type, not just images) to the page.
**Steps:**
1. Open Opera with `--show-component-extension-options` to reveal the hidden 'Opera Touch Background' extension and read its source.
2. Inspect web.flow.opera.com source; note `parser.innerHTML = src[1]` from `e.dataTransfer.getData('text/html')`.
3. Confirm detached-element XSS: `document.createElement('span').innerHTML='<img src=x onerror=alert(1)>'` fires.
4. Build a page that starts an image drag then redirects to web.flow.opera.com so the drop lands on the vulnerable handler.
5. From the XSS context, post to the extension port: `operaTouchBackground.port.postMessage({type:'SEND_FILE',name:'exploit.bat',content:'calc',file_type:'image/png'})`.
6. Then `postMessage({type:'OPEN_FILE',localFileName:'exploit.bat'})` to execute it.
**How found:** Noticed the My Flow page communicated with an extension absent from opera://extensions/; discovered the --show-component-extension-options flag to reveal and read the hidden extension source. Then audited the page's drag-and-drop code and reasoned that dataTransfer is attacker-controllable and detached innerHTML img tags still load, yielding XSS; reviewed extension APIs for SEND_FILE/OPEN_FILE and tested that OPEN_FILE accepts non-image files.
**Exploitation:** Victim begins dragging an image on attacker page; page redirects to web.flow.opera.com; on drop, attacker-controlled text/html flows into innerHTML, firing onerror XSS. The XSS uses the page's access to the privileged Opera Touch Background extension port to write exploit.bat to Downloads/MyFlow and open it, executing calc (arbitrary code).
**Escalation:** Chained low-impact DOM XSS with a hidden high-privilege component extension's native file APIs (SEND_FILE + OPEN_FILE accepting any file type) to escalate from XSS to arbitrary file write and RCE.
**Insight:** Hidden component extensions aren't listed in opera://extensions/ but can be exposed via --show-component-extension-options; when a web page can postMessage to such an extension, treat its native file APIs as an XSS-to-RCE bridge. Also, innerHTML on a detached element still triggers img onerror, so drag-and-drop dataTransfer sinks are live XSS even without rendering.
