Skip to content

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:

Edited by Nick Malcolm