Developers can bypass code owners approval by changing a MR's base branch

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 #2109371 by js_noob on 2023-08-14, assigned to @nmalcolm:

Report | Attachments | How To Reproduce

Report

Summary

Hello team, a project owner can set code owners in his project, the code owners' approvals are required on some branches if it was set by the owner. For example, an owner can set 3 users as code owners and require their approval on MRs that has a base branch as main. However, developers can bypass this by by abusing some really weird behavior happening, where if a code owner approved a specific MR the developer can change the base branch to main (which should explicitly require approvals) and the approvals would persist allowing him to merge this code, that should be approved to be merged on a branch other than main.

Steps to reproduce

As an owner:

  1. Create a new group and apply the ultimate trial to it
  2. Create a new project in that project
  3. Create a CODEOWNERS with the following content, but replace YOUR_USERNAME with your username
[Code Owners]  
* [@]YOUR_USERNAME  
  1. Navigate to Project settings => Repository => Protected branches, and allow Developers + Maintainers to merge to main, and also toggle on Code owner approval

image.png

  1. Navigate to Project settings => Merge requests => Approval settings, check Prevent approval by author, Prevent approvals by users who add commits, and Prevent editing approval rules in merge requests and under When a commit is added: select Remove approvals by Code Owners if their files changed

image.png

  1. Invite a developer to the group

As the developer:

  1. Create a new branch from main called delete-CODEOWNERS and delete the CODEOWNERS file (or you can do that in a single step it doesn't matter)
  2. Create another branch from main let's call my-branch and add any change to the README.md file
  3. From that branch create a MR with delete-CODEOWNERS as the base branch

As the owner:

  1. Approve that newly created MR (at this point the owner is okay to merge these changes into delete-CODEOWNERS only and not main)

As the developer:

  1. Change the base branch of the MR to main, and verify that the approval persists
  2. Merge the MR into main, and verify the success

NOTE: The above bug doesn't work unless the "initial" base branch contains a commit that deletes the CODEOWNERS file, so I am pretty sure there's some weird edge case here leading to this.

Examples/POC

bandicam_2023-08-14_20-04-41-269.mp4

What is the current bug behavior?

Changing the base branch of a MR persists code owners' approvals.

What is the expected correct behavior?

Changing the base branch of a MR should remove code owners' approvals.

Output of checks

This bug happens on GitLab.com

Impact

Unauthorized content is being pushed to protected branches, with impact varying depending on:

  1. Protected GitLab CI/CD variables content
  2. Automated CI/CD

Attachments

Warning: Attachments received through HackerOne, please exercise caution!

How To Reproduce

Please add reproducibility information to this section: