Skip to content

Server-side DoS through rendering crafted Markdown documents in GitLab CE versions

HackerOne report #1090049 by phli on 2021-01-29, assigned to @dcouture:

Report | How To Reproduce

Report

Summary

Self-hosted GitLab CE versions allow users to feed arbitrary Markdown files for rendering. This can be done in the browser user-interface or command-line APIs (i.e., /api/v4/markdown). Some crafted Markdown files trigger some performance bugs in the Markdown renderers and cause server-side to take unexpectedly longer execution time to render. This can potentially make the server unavailable if the crafted file takes too much CPU time. This cannot be mitigated by tuning application limits.

Steps to reproduce

(1. Environment)
Latest GitLab CE version, 13.8.1, more information can be found below.
And operating system:

Linux labpc 4.9.0-11-amd64 #1 SMP Debian 4.9.189-3+deb9u2 (2019-11-11) x86_64 GNU/Linux  

(2. API request)
Directly query the Markdown API with the crafted Markdown document.

input = "```css\n```typescript\n[\n```\n" * 300000  
payload = {'text': input}  
start_time = time.time()  
response = requests.post("http://REDACTED/api/v4/markdown", data=payload) # replace the URL with your own one. This one only works in my own local area network.  
interval = round(time.time() - start_time, 3)  
print(interval)  

(3. user action )
Just wait for the response and check the execution time. I have tried with the repetition of 300000, the corresponding time exceeds 10 seconds. For your reference, I have tried many other normal inputs in the same size, the execution time is mostly within 1 second. This suggests there definitely is a performance issue in the GitLab's Markdown renderer when handling such an input. You can change the number 300000 to others for your testing.

Impact

The server-side CPU consumption increases if the CPUs are occupied by such Markdown requests. Moreover, DoS can be caused and makes all services unavailable to other normal users and operations.

Examples

To avoid to impact on GitLab.com, I DON'T test on GitLab.com. However, I suspect the problem can also appear in GitLab.com.

(If you are using an older version of GitLab, this will also help determine whether the bug has been fixed in a more recent version)
I am using the latest version, at the time of reporting the bug.

What is the current bug behavior?

(What actually happens, include relevant screenshots, API results, or complete HTTP requests)
So, the execution time is much longer than expected.

What is the expected correct behavior?

I expect the rendering to be done within 1 or 2 seconds. The response from the above script can get the rendered HTML content.

Relevant logs and/or screenshots

(Paste any relevant logs - please use code blocks (```) to format console output,
logs, and code as it's very hard to read otherwise.)

Output of checks

(If you are reporting a bug on GitLab.com, write: This bug happens on GitLab.com)

Results of GitLab environment info
System information  
System:		Debian 9.13  
Current User:	git  
Using RVM:	no  
Ruby Version:	2.7.2p137  
Gem Version:	3.1.4  
Bundler Version:2.1.4  
Rake Version:	13.0.3  
Redis Version:	5.0.9  
Git Version:	2.29.0  
Sidekiq Version:5.2.9  
Go Version:	unknown

GitLab information  
Version:	13.8.1  
Revision:	7248f8bff5a  
Directory:	/opt/gitlab/embedded/service/gitlab-rails  
DB Adapter:	PostgreSQL  
DB Version:	12.4  
URL:		http://REDACTED  
HTTP Clone URL:	http://REDACTED/some-group/some-project.git  
SSH Clone URL:	git@REDACTED:some-group/some-project.git  
Using LDAP:	no  
Using Omniauth:	yes  
Omniauth Providers:

GitLab Shell  
Version:	13.15.0  
Repository storage paths:  
- default: 	/var/opt/gitlab/git-data/repositories  
GitLab Shell path:		/opt/gitlab/embedded/service/gitlab-shell  
Git:		/opt/gitlab/embedded/bin/git  

Impact

Sophisticated CPU exhaustion DoS.

How To Reproduce

Please add reproducibility information to this section:

Edited by Dominic Couture