Skip to content

Markdown renderer in Gitlab Workflow VSCode extension allows arbitrary HTML attributes on whitelisted elements

HackerOne report #1261073 by arw9234 on 2021-07-14, assigned to GitLab Team:

Report | Attachments | How To Reproduce

Report

Summary

I'm not sure whether something like this would be accepted without a larger impact, but I figured I should report it nonetheless.

The Gitlab VSCode extension renders gitlab flavored markdown in a few places, mostly just in issues and merge requests. When doing so, it sends the markdown to be rendered to the connected Gitlab instance where it is processed server-side. However, the extension then mutates the resulting HTML with regexes before incorporating it into the document using the following function:

private createMessageHandler = (  
	panel: vscode.WebviewPanel,  
	issuable: RestIssuable,  
	repositoryRoot: string,  
) => async (message: any) => {  
	const instanceUrl = await getInstanceUrl(repositoryRoot);  
	if (message.command === 'renderMarkdown') {  
		let rendered = await gitLabService.renderMarkdown(message.markdown, repositoryRoot); // <--- clean HTML from server  
		rendered = (rendered || '')  
			.replace(/ src=".*" alt/gim, ' alt') // <--- dangerous alteration of HTML with regexes  
			.replace(/" data-src/gim, '" src')  
			.replace(/ href="\//gim, ` href="${instanceUrl}/`);

	// ...  
}

The above code attempts to remove/alter specific attributes within the resulting HTML. In particular, the / src=".*" alt/gim regex tries to remove src attributes followed by an alt attribute, but could be made to break out of quoted attributes or change the nesting order of elements. For example, the following HTML:

<div color=" src=" title="" alt=" someattr='somevalue'"></div>  

Will pass through Gitlab's markdown renderer relatively unchanged (color, title, and alt are whitelisted on all elements, and <div> is a whitelisted element), but the src=" title="" alt sequence would then be matched and replaced by alt with the above regex, resulting in:

<div color=" alt=" someattr="somevalue" "=""></div>  

Where the someattr attribute has broken out of the alt attribute and became part of the DOM. This allows for arbitrary HTML attributes to be added to any element whitelisted by the sanitization filter.

This is limited, however, in that the affected frame is using a nonce-based CSP that restricts inline event handlers and javascript: URIs. If it were possible to inject arbitrary HTML elements as well, it could be possible to inject <iframe>/,<object> tags since the object-src directive is missing from the CSP. This would most likely require gitlab's GFM renderer to emit unescaped angle bracket characters in a quoted attribute, which it does not seem very keen on doing, but I will keep looking into it.

Steps to reproduce

You can reproduce this yourself as follows:

  1. Install Visual Studio Code and the Gitlab Workflow extension
  2. Create a personal access token and add it to the extension to link it to your gitlab account. Instructions can be found here
  3. In a new or existing project, create an issue with the following markdown in the description:
<div color=" src=" title="" alt=" style='display: block; position: absolute; width: 100vw; height: 100vh; left: 0; top: 0; z-index: 999999; background-color: black;' onmouseover='throw /this will raise a CSP violation/'">  
	<h1>arbitrary style attr injected</h1>  
</div>  
  1. Assign the issue to the same user whose access token you used to set up the extension
  2. Clone the repository locally in vscode
  3. If prompted, grant trust to the repository - vscode disables all extensions if you deny trust to the repo
  4. Click the gitlab icon in the left-hand menu
  5. On the left-hand side, expand ISSUES AND MERGE REQUESTS > Issues assigned to me
  6. Open the newly created issue
  7. The editor window will be filled with a black menu with the text 'arbitrary style attr injected', indicating the style attribute was injected into the DOM. You can also open Help > Toggle Developer Tools to see the source code for the page and to see CSP violations printed to the console
Impact

An attacker can submit a malicious issue/merge request to a project that could contain arbitrary HTML attributes on whitelisted elements when opened in vscode. The impact of this is limited with inline event handlers blocked by the CSP, but this could still allow restyling of the page, injecting hrefs with arbitrary protocols on anchor elements (javascript: uris obviously won't be executed, but other protocols could be used, such as custom protocols registered by other applications), and injecting other potentially dangerous attributes.

Examples

See the attached OVA.

What is the current bug behavior?

The markdown renderer in the GitLab Workflow VSCode extension uses a poorly designed regex to alter attributes on HTML elements which can be induced to change the structure of the HTML returned from the server.

What is the expected correct behavior?

The markdown renderer should either:
- not change the HTML returned from the server, or
- parse the HTML and update the relevant attributes using setAttribute(...)/removeAttribute(...)/similar before inserting it into the DOM
so that the structure of the document is not changed

Relevant logs and/or screenshots

Below is a screenshot of what the window should look like after opening the issue:
VSCode_Extension_Attr_Injection_1.png

Below is a screenshot showing the CSP violations printed to the console due to the onmouseover handler:
VSCode_Extension_Attr_Injection_2.png

Output of checks

Not applicable to GitLab.com

Results of GitLab environment info

N/A

Best regards,
[@]arw9234

Impact

An attacker can submit a malicious issue/merge request to a project that could contain arbitrary HTML attributes on whitelisted elements when opened in vscode, allowing for restyling of the page, injecting hrefs with arbitrary protocols on anchor elements, and injecting other potentially dangerous attributes. A CSP bypass or ability to inject <object> tags could potentially increase impact.

Attachments

Warning: Attachments received through HackerOne, please exercise caution!

How To Reproduce

Please add reproducibility information to this section:

Edited by Dominic Couture