# Google Cloud Shell XSS

Theia webview in Google Cloud Shell lacked origin isolation and trusted postMessage, letting any opener inject script and run terminal commands.

- Payout: $5,000
- Severity: high
- Program: Google
- Credited: NDevTK
- Disclosed: 2021-12-30
- CVE: CVE-2021-41038
- Write-up quality: 7/10
- Original: https://ndevtk.github.io/writeups/2021/12/30/cloud-shell-xss/
- Library page: https://bugbountylibrary.com/r/blog%3Andevtk-github-io-writeups-2021-12-30-cloud-shell-xss
- Tags: domain:web impact:internal-access impact:rce kind:bounty platform:blog sev:high tech:nodejs technique:chained technique:js-analysis vuln:rce vuln:xss

**Target:** Theia IDE webview embedded in shell.cloud.google.com
**Root cause:** Webviews used allow-same-origin so they were not unique-origin sandboxed, and the message listener trusted messages from any origin, allowing arbitrary HTML/script injection and RUN_IN_TERMINAL commands.
**Steps:**
1. Load `https://shell.cloud.google.com/?show=ide&opencloudcodewelcome=true` to auto-embed Theia and open a webview.
2. From an opener window, send `w[2][0].postMessage({channel:'content',args:{options:{allowScripts:true},contents:'<script>document.write(document.domain)</script>'}},'*')` to inject script into the webview.
3. Send `{target:'<webview id>',channel:'onmessage',data:{text:"echo ':)'",type:'RUN_IN_TERMINAL'}}` to execute terminal commands.
**How found:** Reading the cloudshell JS bundle revealed the opencloudcodewelcome parameter auto-embeds Theia and opens a webview; reviewing Theia's webview message listener showed it accepted messages from any origin and lacked unique-origin sandboxing.
**Exploitation:** Attacker hosts a page that opens the Cloud Shell URL with opencloudcodewelcome, obtains a handle to the embedded webview, and postMessages arbitrary HTML with allowScripts to achieve XSS, then sends RUN_IN_TERMINAL messages to execute commands in the victim's Cloud Shell terminal.
**Escalation:** XSS in the webview escalates to terminal command execution via the RUN_IN_TERMINAL postMessage handler, and the webview can request GCP API access.
**Insight:** When a web IDE embeds webviews, check whether allow-same-origin defeats the unique-origin sandbox and whether the postMessage listener validates event.origin/source; also grep the host app's JS bundle for URL params that auto-open webviews, giving an attacker a handle without user interaction.
