Spoofing of the contents of a protected branch by creating a tag with the same name as the protected branch
HackerOne report #2121310 by ricardobrito on 2023-08-23, assigned to GitLab Team:
Report | Attachments | How To Reproduce
Report
Hi team,
Summary
I have found that it is possible for a user with developer role to spoof the contents of a protected branch by creating a tag with the same name as the protected branch.
Pre-requisites
- An instance admin account.
- A normal user - User A
- A normal user - User B
- Create an access token for user A
- Create an access token for user B
Steps to reproduce
-
As the instance admin, create a private group called
admin-group -
As the instance admin, create a project (private) called
admin-projectinside the group created in step 1. -
As the instance admin (now group owner), invite User A and User B as developers.
-
As the group owner, create a file called
.gitlab-ci.ymlinside the project with the following content:
build-job:
stage: build
script:
- echo "Hello, ADMIN"
- As the group owner, edit the
.gitlab-ci.ymlfile using the gitlab ide:
change the contents to:
build-job:
stage: build
script:
- echo "Hello, ADMIN FROM BRANCH"
Commit the changes to a new branch called devel
- Still as the owner, go to the repository settings -> expand the Protected branches section, select the
develbranch and set the following rules:
Allowed to merge: maintainrers
Allowed to push and merge: maintainrers
Press the protect button
- As user A, clone the project using the gitlab token, with the following command:
git clone http://USER-A:glpat-_USER-A-TOKEN@YOUR-GITLAB-INSTANCE/admin-group/admin-project
Then run the following commands:
cd admin-project
git checkout origin/devel -b devel_tag
- Still as User A, edit the file
.gitlab-ci.ymlwith the following contents (locally):
build-job:
stage: build
script:
- echo "Hello, USER A"
and save the changes.
- Still as User A, run the following commands:
git add -A
git commit -m "attack"
git push origin devel_tag:refs/tags/devel
This will push the changes to a new tag called devel.
- As User B, go to http://YOUR-GITLAB-INSTANCE/admin-group/admin-project, and click on the branches button (which should show 2, as highlighted below):
Click on the highlighted section in the image above and it will take you to http://127.0.0.1:3000/admin-group/admin-project/-/branches, where you will see 2 branches: main and devel (which is the protected branch that neither USER A or USER B have permission to push code to).
- As user B, click on the
develbranch and you should see that it shows the contents that were commited and pushed by User A instead of the original protecteddevelbranch. (** Impact: The contents of the protected branch have been spoofed by a user who does not have push rights into the branch, allowing him to deliver fake content to other users**)
If User B clicks on the .gitlab-ci.yml file, he will see the contents pushed by User A:
- Still as user B, clone the project locally using the gitlab token and cd into the directory and run the following command:
git checkout devel
Then open the .gitlab-ci.yml file and you will see that it contains the contents pushed by User A, instead of the original contents of the protected branch.
Impact
The impact here is two-fold:
-
After User A makes changes to the protected branch and pushes the changes into a tag with the same name as the protected branch (say
devel), whoever visits the branches page in the UI of the project and clicks on thedevelbranch, will see the changes pushed by user A instead of seeing the contents of the original protected branch. -
If another user clones the project and checks out the
develbranch, he will be checking out the contents of the tag pushed by User A instead of the original protected branch.
Impact
The impact here is two-fold:
-
After User A makes changes to the protected branch and pushes the changes into a tag with the same name as the protected branch (say
devel), whoever visits the branches page in the UI of the project and clicks on thedevelbranch, will see the changes pushed by user A instead of seeing the contents of the original protected branch. -
If another user clones the project and checks out the
develbranch, he will be checking out the contents of the tag pushed by User A instead of the original protected branch.
Attachments
Warning: Attachments received through HackerOne, please exercise caution!
How To Reproduce
Please add reproducibility information to this section:




