ReDoS in message formater using Slack notifications integration that can fully occupy Sidekiq utilization
: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 #2428902](https://hackerone.com/reports/2428902)** by `joaxcar` on 2024-03-21, assigned to @cmaxim: [Report](#report) | [Attachments](#attachments) | [How To Reproduce](#how-to-reproduce) ## Report #### Summary Hi team! I think this is my last ReDoS issue :) when I first found this one, I did not understand the impact, but after learning more about Sidekiq, I now see that this one also has the potential for high availability impact. An attacker can configure Slack notifications as an `integration.` This is done by providing an `incoming webhook` to a Slack app. When a new issue is created, a message will be sent to the Slack app, and it will be posted in the designated Slack channel. When GitLab is preparing the issue description to be sent to Slack this code will run ```ruby RELATIVE_LINK_REGEX = %r{!\[[^\]]*\]\((/uploads/[^\)]*)\)} ... def format_relative_links(string) string.gsub(RELATIVE_LINK_REGEX, "#{project_url}\\1") end ``` Which tries to extract markdown image links `![]()`. This `RELATIVE_LINK_REGEX` is subject to polynomial complexity when evaluated against a long string of this format ```js "![".repeat(500000) ``` If an attacker sets up an integration like this and starts creating issues with this string as described, this regexp will run inside the Sidekiq process. These jobs in Sidekiq do not look like having any timeout and will run for a very long time. By default, Sidekiq has 20 threads to run jobs with. By creating a minimum of 20 issues in the project, the attacker will thus block Sidekiq from processing other background jobs for the server (such as sending emails, creating pipelines, and exporting/importing projects etc). #### Steps to reproduce Test this on a self hosted server 1. Log in as the attacker 2. Create a new project 3. Go to `https://gitlab.example.com/GROUP/PROJECT/-/settings/integrations/slack/edit` 4. Fill out the form and leave all checkboxes checked. And write any URL in the webhook bar. I don't think you need to create a really webhook; the attack seems to work anyway. 5. Now go to `https://gitlab.com/GROUP/PROJECT/-/issues/new` give it a name 6. Open devtools and run this` ```js "![".repeat(500000) ``` Click the small "copy" icon to copy the output 7. Put the long string in the description and click create (make sure to keep the network tab of devtools open) 8. When the request is done, filter for `issues` in the network tab of dev tools, find the post request, and right-click it. Open "copy" and click "copy as fetch" 9. in the console of devtools run the copied command 20+ times 10. Log in as an admin user to the gitlab instance. 11. Go to `https://gitlab.com/GROUP/PROJECT/admin/background_jobs` and you should see something like this ![blocked1.png](https://h1.sec.gitlab.net/a/f9c0e945-b5bb-428a-891a-0be796d6fb68/blocked1.png) ![blocked2.png](https://h1.sec.gitlab.net/a/41d8164a-3918-4a7f-9733-520582179b1e/blocked2.png) The 20 Blocking jobs should be your Integration jobs. The request queue should eventually just grow as the jobs are blocking all 20 threads. #### Impact ReDoS issue allows to block all threads in Sidekiq which will block all other background jobs to run #### What is the current *bug* behavior? The `RELATIVE_LINK_REGEX` regexp is subject to polynomial runtime #### What is the expected *correct* behavior? The regexp should be restricted in size or have other limits #### Output of checks ##### Results of GitLab environment info ``` System information System: Debian 12 Proxy: no Current User: git Using RVM: no Ruby Version: 3.1.4p223 Gem Version: 3.5.5 Bundler Version:2.5.5 Rake Version: 13.0.6 Redis Version: 7.0.15 Sidekiq Version:7.1.6 Go Version: unknown GitLab information Version: 16.9.2-ee Revision: 0d71d32d321 Directory: /opt/gitlab/embedded/service/gitlab-rails DB Adapter: PostgreSQL DB Version: 14.10 Elasticsearch: no Geo: no Using LDAP: no Using Omniauth: yes Omniauth Providers: GitLab Shell Version: 14.33.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: 16.9.2 - default Git Version: 2.43.0 ``` #### Impact ReDoS issue allows to block all threads in Sidekiq which will block all other background jobs to run ## Attachments **Warning:** Attachments received through HackerOne, please exercise caution! * [blocked1.png](https://h1.sec.gitlab.net/a/f9c0e945-b5bb-428a-891a-0be796d6fb68/blocked1.png) * [blocked2.png](https://h1.sec.gitlab.net/a/41d8164a-3918-4a7f-9733-520582179b1e/blocked2.png) ## 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