DOS: Taking down a 1k-users Gitlab EE self-manage instance by testing a malicious external wiki URL in a project's settings
:warning: **Please read [the process](https://gitlab.com/gitlab-org/release/docs/-/blob/master/general/security/developer.md) on how to fix security issues before starting to work on the issue. Vulnerabilities must be fixed in a security mirror.** **[HackerOne report #2629934](https://hackerone.com/reports/2629934)** by `a92847865` on 2024-07-30, assigned to `GitLab Team`: [Report](#report) | [Attachments](#attachments) | [How To Reproduce](#how-to-reproduce) ## Report > NOTE! Thanks for submitting a report! Please note that initial triage is handled by HackerOne staff. They are identified with a `HackerOne triage` badge and will escalate to the GitLab team any. Please replace *all* the (parenthesized) sections below with the pertinent details. Remember, the more detail you provide, the easier it is for us to triage and respond quickly, so be sure to take your time filling out the report! ##### Summary Gitlab allows [adding a link to an external wiki to a project](https://docs.gitlab.com/ee/user/project/wiki/#link-an-external-wiki). Before saving external wiki's URL, user can validate if that URL is valid or not. To validate that URL, Gitlab application sends a request to the http server hosting external wiki. Due to lack of content-encoding validation, a malicious server can respond to Gitlab application with a zip-bomb (small gzip file but inflating to GBs in memory). It is possible to cause OOM to a 1k-user Gitlab instance with just 3 requests. ##### Steps to reproduce 1. Register two VMs: a ```1k-users self-hosted Gitlab EE instance ``` VM (8 vCPU, 16GB RAM) and another ```external_wiki_server``` smaller VM. 2. Install latest Gitlab EE on ``1k-users self-hosted Gitlab EE instance``` VM. 3. Create a new project. 4. Upload these files (![wiki_server.js](https://h1.sec.gitlab.net/a/ce3386b3-056f-4bea-bba2-20908010cb64/wiki_server.js) and ![report.json.gz](https://h1.sec.gitlab.net/a/fbaf8bd9-7e5b-4831-b700-f745978243c0/report.json.gz))to ```external_wiki_server``` VM 5. Start ```external_wiki_server``` at port 80: ```sudo nodejs wiki_server.js``` 6. Open 3 tabs with the same below URL. You can find equivalent curl command using Chrome's Developer Tools and send 3 requests by curl also. It would be the way to automate this attack for larger instances. ```http://[your_GL's_host_name]/[optional_group_name]/[project_name]/-/settings/integrations/external_wiki/edit``` 7. Fill in "External wiki URL" field of each tab with ```http://[external_wiki_server_IP]/[anything]``` and click "Test settings" button 8. SSH into ```1k-users self-hosted Gitlab instance ``` VM, run "htop" command. You should see that Gitlab consumes all available memory and the Gitlab instance becomes unavailable. ##### Impact DOS: complete service outage to other users. ##### Examples (If the bug is project related, please create an example project and export it using the project export feature) (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) (If the bug can be reproduced on GitLab.com without violating the `Rules of Engagement` as outlined in the program policy, please provide the full path to the project.) ##### What is the current *bug* behavior? Gitlab::HTTP gem doesn't validate "Content-Encoding" header of responses from external_wiki_server. A malicious server can send a zip-bomb as response body. Net/HTTP gem (the under-the-hood HTTP client of httparty and indirectly Gitlab::HTTP gem) decompresses the zip bomb automatically. This behavior could lead to uncontrolled resource (RAM) consumption. ##### What is the expected *correct* behavior? Gitlab::HTTP gem should validate "Content-Encoding" header of responses from untrusted servers, deny all responses with a compressed format "Content-Encoding" header. ##### 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 (For installations with omnibus-gitlab package run and paste the output of: `sudo gitlab-rake gitlab:env:info`) ``` System information System: Ubuntu 20.04 Proxy: no Current User: git Using RVM: no Ruby Version: 3.1.5p253 Gem Version: 3.5.11 Bundler Version:2.5.11 Rake Version: 13.0.6 Redis Version: 7.0.15 Sidekiq Version:7.1.6 Go Version: unknown GitLab information Version: 17.2.1-ee Revision: 88793996279 Directory: /opt/gitlab/embedded/service/gitlab-rails DB Adapter: PostgreSQL DB Version: 14.11 URL: http://34.16.168.95 HTTP Clone URL: http://34.16.168.95/some-group/some-project.git SSH Clone URL: git@34.16.168.95:some-group/some-project.git Elasticsearch: no Geo: no Using LDAP: no Using Omniauth: yes Omniauth Providers: GitLab Shell Version: 14.37.0 Repository storages: - default: unix:/var/opt/gitlab/gitaly/gitaly.socket GitLab Shell path: /opt/gitlab/embedded/service/gitlab-shell Gitaly - default Address: unix:/var/opt/gitlab/gitaly/gitaly.socket - default Version: 17.2.1 - default Git Version: 2.45.2 ``` (For installations from source run and paste the output of: `sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production`) #### Impact Attacker can take down a 1k-users Gitlab EE self-manage instance by testing a malicious external wiki URL in a project's settings. It would make the Gitlab EE instance unavailable to other users. ## Attachments **Warning:** Attachments received through HackerOne, please exercise caution! * [wiki_server.js](https://h1.sec.gitlab.net/a/ce3386b3-056f-4bea-bba2-20908010cb64/wiki_server.js) * [report.json.gz](https://h1.sec.gitlab.net/a/fbaf8bd9-7e5b-4831-b700-f745978243c0/report.json.gz) ## How To Reproduce Please add [reproducibility information] to this section: 1. 1. 1. [reproducibility information]: https://about.gitlab.com/handbook/engineering/security/#reproducibility-on-security-issues
issue