Writeups

This is an attempt to make a better write up than 575924 – (CVE-2021-41038) XSS in @theia/plugin-ext webview :) (It’s a Theia bug but Google paid for improving the security of the project after some discussion.)

https://shell.cloud.google.com/ embeds the Theia IDE from a subdomain of “cloudshell.dev” that can request access to the GCP API via postMessage(), So bugs in the Theia project may affect the security of Google Cloud. (it’s not on the Public Suffix List, used to be on appspot.com that is listed) I’m not sure when the API opt in was added, I think it used to have credentials by default.

window.parent.postMessage({
    "target": "ID from URL of webview",
    "channel": "onmessage",
    "data": {
        "type": "LOG_IN"
    }
}); // Childs are trusted just rename “channel” to “command” and remove “target”.

Theia has an implementation of the VS Code webviews which are like iframes and are used to render arbitrary html this can be done via postMessage() from any origin. (message listener) (assignment)

For security webviews are meant to use a unique origin so the sandbox restrictions get enforced but they don’t due to the “allow-same-origin”. (What I’ve learned so far while bringing VS Code’s Webviews to the web – UWTB).

Google Cloud Shell does not isolate webviews into their own origins like said here and the webviews are allowed to run terminal commands anyway via postMessage()

window.parent.postMessage({
    "target": "ID from URL of webview",
    "channel": "onmessage",
    "data": {
        "text": "echo ':)'",
        "type": "RUN_IN_TERMINAL"
    }
});

However they do use CSP frame-ancestors to block embedding of the IDE and its webviews, Content-Security-Policy: frame-ancestors 'self' https://*.corp.google.com:* https://*.sandbox.google.com:* https://*.googleplex.com:* https://byteboard.googleplex.com https://byteboard.dev https://edge.byteboard.dev https://enginterview.withgoogle.com https://console.cloud.google.com https://ide.cloud.google.com https://shell.cloud.google.com https://ssh.cloud.google.com; So to prevent webview hijacking/xss Theia now checks that messages are from window.parent or a child of the webview. (Change) Other web IDEs may still be vulnerable if the webviews have no embedding protection like “vscode-webview.net” (Fixed CVE-2022-24526) or they have copied from VS Code, However VS Code now uses MessageChannel and only sends to window.parent.

Exploitation

In order to exploit this an attacker needs to send a message to the webview. After looking at the code in https://www.gstatic.com/_/cloudshell/_/js/ I found that using the “opencloudcodewelcome” URL parameter it will embed Theia and open a webview automatically. https://shell.cloud.google.com/?show=ide&opencloudcodewelcome=true (this now uses COOP allow-popups so the opener can’t be exploited)

Then to get XSS any opener can send a message to the embedded webview.

w[2][0].postMessage({channel: "content", args: {options: {allowScripts: true}, contents: "<script>document.write(document.domain)</script>"}}, "*");