Skip to content

Bug with CODEOWNERS approval removal allows to merge arbitrary code into protected branches

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 #1928709 by glan1k on 2023-03-31, assigned to @ottilia_westerlund:

Report | How To Reproduce

Report

Summary

In case of enabled CODEOWNERS, and "Remove approvals by Code Owners if their files changed" is checked (1), it's possible to push new code which is related to one or more CODEOWNERS, but approve won't be removed

Such vulnerability allows attacker to push arbitrary, unapproved code after the initial approval, and compromise protected branches code/variables, and ultimately - production environments

(1) https://docs.gitlab.com/ee/user/project/merge_requests/approvals/settings.html#remove-approvals-by-code-owners-if-their-files-changed

Steps to reproduce

(Step-by-step guide to reproduce the issue, including:)

  1. Create GItLab Repository
  2. Create user "repo_approver_user" as Developer in repository
  3. Create user "repo_attacker_user" as Developer in repository
  4. Enable CODEOWNERS (1) in repository settings
  5. Enable "Remove approvals by Code Owners if their files changed" in repository settings (2)
  6. Push CODEOWNERS file to main branch with content like "* repo_approver_user" so everything will require approve by "repo_approver_user"
  7. Make CODEOWNERS approval mandatory for protected branch main (3)
  8. Create new branch "feature_branch" from "repo_attacker_user"
  9. In local copy, make safe change, push it to remote, and create MR from "repo_attacker_user"
  10. Receive approve from "repo_approver_user"
  11. In locally copy, change files to arbitrary malicious code to compromise production, or .gitlab-ci.yml change to steal protected variables
  12. Do "git amend" and "git push -f" to remote
  13. Malicious code in remote branch, approve still in place
  14. Merge code into protected main branch as "repo_attacker_user"

(1) https://docs.gitlab.com/ee/user/project/code_owners.html
(2) https://docs.gitlab.com/ee/user/project/merge_requests/approvals/settings.html#remove-approvals-by-code-owners-if-their-files-changed
(3) https://docs.gitlab.com/ee/user/project/protected_branches.html#require-code-owner-approval-on-a-protected-branch

Impact

Varies from low to high, depending on:

  1. Protected GitLab CI/CD variables content
  2. Automated CI/CD to production
  3. Many other factors

In worst case:

Production environment to which protected branch is eventually deployed, could be compromised including confidential data leak, and integrity compromise

Or

Credentials are stollen from protected GitLab CI/CD variables, and used to compromise production environment, including confidential data leak, and integrity compromise

Examples

GitLab instance is self-hosed and not available from the internet, bug is not tested in cloud GitLab, but probably the same

What is the current bug behavior?

New code related to CODEOWNERS is pushed, approvals from relevant CODEOWNERS remain in place

What is the expected correct behavior?

New code related to CODEOWNERS is pushed, approvals from relevant CODEOWNERS removed

Relevant logs and/or screenshots

No relevant logs, or screenshots

Should be easy to reproduce using "Steps to reproduce"

Output of checks

GitLab.com was not tested

Results of GitLab environment info
System information  
System:  
Proxy:          no  
Current User:   git  
Using RVM:      no  
Ruby Version:   2.7.7p221  
Gem Version:    3.1.6  
Bundler Version:2.3.15  
Rake Version:   13.0.6  
Redis Version:  6.2.8  
Sidekiq Version:6.5.7  
Go Version:     unknown

GitLab information  
Version:        15.9.3-ee  
Revision:       d3356768b48  
Directory:      /opt/gitlab/embedded/service/gitlab-rails  
DB Adapter:     PostgreSQL  
DB Version:     12.12  
URL:            https://gitlab.*REDACTED*.com  
HTTP Clone URL: https://gitlab.*REDACTED*.com/some-group/some-project.git  
SSH Clone URL:  ssh://git@gitlab.*REDACTED*.com:2222/some-group/some-project.git  
Elasticsearch:  no  
Geo:            no  
Using LDAP:     no  
Using Omniauth: yes  
Omniauth Providers: saml

GitLab Shell  
Version:        14.17.0  
Repository storages:  
- default:      unix:/var/opt/gitlab/gitaly/gitaly.socket  
GitLab Shell path:              /opt/gitlab/embedded/service/gitlab-shell  

Impact

Varies from low to high, depending on:

  1. Protected GitLab CI/CD variables content
  2. Automated CI/CD to production
  3. Many other factors

In worst case:

Production environment to which protected branch is eventually deployed, could be compromised including confidential data leak, and integrity compromise

Or

Credentials are stollen from protected GitLab CI/CD variables, and used to attack compromise production environment, including confidential data leak, and integrity compromise

How To Reproduce

Please add reproducibility information to this section: