CSRF via file upload allows an attacker to take over a repository.
HackerOne report #1778009 by st4nly0n
on 2022-11-18, assigned to Ottilia Westerlund
:
Report | Attachments | How To Reproduce
Report
Summary
The default branch name for a group is not being validated correctly, when uploading a file from the web interface, a POST request is issued that includes in the request path the default branch name of a group.
POST /any_path HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 Firefox/106.0
Accept: application/json, text/plain, */*
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost/user/repo
X-CSRF-Token: REDACTED
X-Requested-With: XMLHttpRequest
Content-Type: multipart/form-data; boundary=---------------------------367269929429674248332090673842
Content-Length: 653
Origin: http://localhost
Connection: close
Cookie: _gitlab_session=REDACTED; event_filter=all
-----------------------------367269929429674248332090673842
Content-Disposition: form-data; name="branch_name"
../../../../../any_path
-----------------------------367269929429674248332090673842
Content-Disposition: form-data; name="create_merge_request"
true
-----------------------------367269929429674248332090673842
Content-Disposition: form-data; name="commit_message"
Upload New File
-----------------------------367269929429674248332090673842
Content-Disposition: form-data; name="file"; filename="anyfile.txt"
Content-Type: text/plain
-----------------------------367269929429674248332090673842--
This allows to place in the main branch name a path with traversal path to any api endpoint and issue POST requests with the current session.
The endpoint /api/v4/projects/<ID-VICTIM-PROJECT>/import_project_members/<ID-ATTACKER-PROJECT>
, allows importing members from one project to another, if the victim issues a POST request to this endpoint it would be importing the members with the source permissions to the target repository.
An attacker can take over the victim's repository through the use case where a victim decides to use the web interface to upload a file to an empty repository to which he was invited.
Steps to reproduce:
• Perform the steps below as the victim user:
1. The user owner
creates a public repository named project_victim
.
• Perform the following steps as the attacker user:
1. Create two accounts attacker1
and attacker2
.
2. attacker1
creates a public group called attacker_group
3. attacker1
creates an empty public project (uninitialized README.md) named attacker_project
inside the attacker_group
group.
4. attacker1
changes the default branch name for the attacker_group
group to the following value:
### branch name obfuscated
main.182BB2A57D285B692BB93108E937f12bbfe9c15748A8A271dc238B895683B34D2273571f8753cbb9fB466CF4D395da5fe784340150e485f3378f01d2450ff7eed56308c0f6f4ebc364189714C1f74140f97../../../../../../api/v4/projects/<ID-VICTIM-PROJECT>/import_project_members/<ID-ATTACKER-PROJECT>
where ID-VICTIM-PROJECT
is the project id of project_victim
and ID-ATTACKER-PROJECT
is the project id of attacker_project
.
5. attacker1
invites attacker2
to the attacker_project
repository, and gives him the role of owner.
6. attacker1
invites user owner
to the attacker_project
project and grants him the role of maintainer.
7. the owner
user uses the web interface to upload a file to the attacker_project
.
As a result of this behavior, user attacker2
owns the project project_victim
project.
The attack also succeeds if the owner
user is replaced by a maintainer user of the project project_victim
project, since a maintainer can import members from other projects.
What is the current bug behavior?
A victim using the web interface to upload a file to an empty repository to which he was invited would be granting access to any user within the victim's repository.
What is the expected correct behavior?
You must validate the main branch name for a group correctly, git does not allow a branch name like this '../../'.
Relevant logs and/or screenshots
The following video shows the attack starting from step 7 in the steps to replay, see how the victim decides to use the web interface to upload a file to an empty repository to which he was invited, this allowed an attacker to own a repository of the victim.
poc.mp4
Output of checks
This bug happens on GitLab.com
Impact
An attacker can take control of any victim's repository, using the use case where a victim decides to use the web interface to upload a file to a repository to which he was invited.
Attachments
Warning: Attachments received through HackerOne, please exercise caution!
How To Reproduce
Please add reproducibility information to this section: