Bug with CODEOWNERS approval removal allows to merge arbitrary code into protected branches
:warning: **Please read [the process](https://gitlab.com/gitlab-org/release/docs/-/blob/master/general/security/developer.md) on how to fix security issues before starting to work on the issue. Vulnerabilities must be fixed in a security mirror.**
**[HackerOne report #1928709](https://hackerone.com/reports/1928709)** by `glan1k` on 2023-03-31, assigned to @ottilia_westerlund:
[Report](#report) | [How To Reproduce](#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)
5) Push CODEOWNERS file to main branch with content like "* repo_approver_user" so everything will require approve by "repo_approver_user"
6) Make CODEOWNERS approval mandatory for protected branch main (3)
7) Create new branch "feature_branch" from "repo_attacker_user"
8) In local copy, make safe change, push it to remote, and create MR from "repo_attacker_user"
9) Receive approve from "repo_approver_user"
10) In locally copy, change files to arbitrary malicious code to compromise production, or .gitlab-ci.yml change to steal protected variables
11) Do "git amend" and "git push -f" to remote
12) Malicious code in remote branch, approve still in place
13) 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:
1.
1.
1.
[reproducibility information]: https://about.gitlab.com/handbook/engineering/security/#reproducibility-on-security-issues
issue