Introduction

Google Cloud Shell is a product of the Google Cloud Platform (GCP) that provides a number of interesting features, such as an interactive shell environment and an integrated code editor, with the intent of making experimenting and administration of GCP products easier while requiring very little setup.

As part of the Google Vulnerability Reward Program (VRP) I discovered that the code editor of the Cloud Shell was vulnerable to Cross-Site Scripting (XSS) embedded into Scalable Vector Graphics (SVG) files.

Discovery

While experimenting with the code editor I was curious to see how it would handle SVG files, which are XML-based vector image files. I decided to download a simple SVG file to the Cloud Shell environment and then clicked on the file in the editor's file navigator. Interestingly the file was not opened in edit mode but rather in preview mode, that is the file was rendered by my browser as an image.

svg-preview.png

Figure 1: A SVG file previewed inside the editor.

A little-known detail of the SVG specification is its support for scripting. While the HTML standard disallows the execution of such scripts in certain contexts such as the img element it allows script execution in other contexts such as the iframe element unless explicitly disallowed a mechanism known as sandboxing which can be activated by the sandbox attribute of an iframe or by the sandbox directive of a Content Security Policy (CSP).

Being aware of this I decided to check how the image was embedded into the editor. It turned out that the image was included using an iframe element with a sandbox attribute containing, amongst others, the allow-same-origin and the allow-scripts keywords, which lifts certain sandbox restrictions and thus should effectively allow the execution of arbitrary scripts embedded into the SVG file. As a matter of fact, the listed attributes were the default sandbox options of the mini-browser extension of the Theia IDE, upon which Google Cloud Shell's code editor is based.

iframe-sandbox.png

Figure 2: The SVG file being embedded using an iframe.

To test my assumptions I modified the SVG file so that when loaded it would simply show the file's location in case the script gets executed. I then opened the file by clicking on it, which confirmed that the code editor was vulnerable to XSS embedded into SVG files.

svg-script-execution.png

Figure 3: A SVG file whose embedded script gets executed when previewed inside the editor.

Exploitability

For the described vulnerability to be not only of theoretical interest the impact of a potential attack must be non-negligible and the potential attack must not be merely self-XSS.

Impact

The impact of a potential attack is determined by the domain in whose context the XSS payload would be executed. As can be seen the domain would be of the form 970-dot-123456789-dot-devshell.appspot.com. Further analysis revealed that the domain name varies for every Cloud Shell user. Apparently a unique ID is assigned to each Cloud Shell user and the domain 970-dot-$ID-dot-devshell.appspot.com, which is only accessible by the associated user, is used to address the backend of that user's Cloud Shell code editor. Each Cloud Shell user is assigned an isolated virtual machine where this and other Cloud Shell backend services are hosted.

Consequently, the code of the XSS payload would be able to unrestrictedly communicate with the editor's backend, which in particular allows executing arbitrary commands on the assigned user's virtual machine. A potential attacker thus could obtain access to a Cloud Shell user's GCP resources as the virtual machine is automatically authorized to access these resources.

Attack scenario

For a potential attacker to exploit the described vulnerability they would have to trick a Cloud Shell user to put a malicious SVG file in their Cloud Shell environment and subsequently click on the file in Cloud Shell's editor. Google Cloud Shell has a feature to create a link that, when clicked, opens Cloud Shell and clones a specified git repository from GitHub or Bitbucket. Additionally, a tutorial file to be displayed to the user after cloning the repository can be specified in the link.

Using this feature, an attacker could put a malicious SVG file inside an interesting looking repository and also include a tutorial in which the Cloud Shell user would be instructed to take a look at the new logo by clicking on the SVG file. The "Open in Cloud Shell" link for cloning the repository and opening the tutorial could then be added to the repository's description.

Fix

After creating a proof of concept and reporting the vulnerability to Google it was fixed. This was done by overriding the editor's mini-browser's default sandbox options as follows, thus effectively serving files in iframes with completely restrictive iframes:

(MiniBrowserProps.SandboxOptions.DEFAULT as any) = []

After the fix was applied, when trying to open a SVG file with an embedded script inside Cloud Shell's editor, as expected the code would be blocked instead of executed.

svg-script-blocked.png

Figure 4: A SVG file whose embedded script gets blocked by the iframe's sandbox when previewed inside the editor.

While this fix protects from the attack scenario described above, it would not be sufficient when a malicious SVG file, or even HTML file, were to be opened inside its own browser window instead of inside the the sandboxed iframe. To protect against such a scenario the files could be protected by the sandbox directive of a CSP. More details about a related vulnerability, which was fixed by applying this CSP directive to all endpoints of the editor's mini-browser, can be found here.

Take away messages

  • Even innocent-looking file formats such as image formats may contain potentially dangerous content. Google Cloud Shell editor had automatic preview mode only enabled for certain file formats like SVG, so the described attack scenario would not have worked with HTML files as these would be opened in edit mode instead.
  • When integrating components, such as the Theia IDE, into larger projects, such as Google Cloud Shell, it is necessary to check whether the component's security related default settings, such as the default sandbox options, are also adequate within the context of the larger project or customization is required.