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