Background
GitLab is an open-source DevOps platform providing source code management, CI/CD, security scanning, and project management capabilities. It is used by over 30 million registered users and thousands of enterprises, including organisations that host their entire software development lifecycle on self-managed GitLab instances. GitLab repositories often contain proprietary source code, deployment secrets, infrastructure-as-code, and CI/CD credentials — making account takeover attacks particularly damaging.
CVE-2023-7028 is a CVSS 10.0 account takeover vulnerability in GitLab CE/EE, disclosed in January 2024. The vulnerability allows unauthenticated attackers to send password reset emails for any account to an attacker-controlled email address, without any interaction from the victim. This provides complete account takeover capability against every account on an affected GitLab instance, including administrator accounts. CISA confirmed active exploitation and added it to the KEV catalogue.
Technical Mechanism
CVE-2023-7028 exploits a logic flaw in GitLab’s password reset functionality. GitLab’s email-based password reset flow is intended to work as follows:
- User requests a password reset and provides their email address
- GitLab validates the email address belongs to an account
- GitLab sends a reset link to that account’s registered email address
The vulnerability is in step 3. GitLab’s password reset endpoint accepts a list of email addresses for the reset notification. The logic intended to send the reset link only to addresses verified to belong to the target account had a flaw: an attacker could supply both the target’s email and an attacker-controlled email in the request, and GitLab would send the reset link to both addresses.
# Normal password reset request
POST /users/password HTTP/1.1
Content-Type: application/x-www-form-urlencoded
user[email][email protected]
# Malicious request exploiting CVE-2023-7028
POST /users/password HTTP/1.1
Content-Type: application/x-www-form-urlencoded
user[email][][email protected]&user[email][][email protected]
By submitting the email field as an array (user[email][] instead of user[email]), the application processes multiple email recipients for the password reset notification. GitLab’s Ruby on Rails backend processes the array and sends the password reset token to both the legitimate account email and the attacker’s email.
The attacker then uses the received reset token to set a new password for the victim’s account. This works against any account including administrators, and requires:
- No credentials
- No interaction from the victim
- Only knowledge of the target user’s email address (easily discoverable from GitLab’s user profile, commit history, or public repositories)
If the victim account has two-factor authentication (2FA) enabled, the attacker still obtains the reset token but will be challenged for the 2FA code. However, accounts without 2FA are completely takeable.
Real-World Exploitation Evidence
CISA confirmed active exploitation of CVE-2023-7028 in May 2024 when adding it to the KEV catalogue. Documented exploitation:
- Administrator account targeting: Attackers specifically targeted GitLab administrator accounts to gain full instance control.
- CI/CD credential harvesting: Post-exploitation activity focused on extracting CI/CD credentials stored in GitLab variables, tokens, and pipeline configurations.
- Source code exfiltration: Private repositories were accessed and exfiltrated following account takeover.
- Runner token theft: GitLab CI runner registration tokens, which allow registering arbitrary CI runners that can execute pipeline jobs, were a primary target.
The vulnerability is particularly insidious because it leaves minimal logs — the victim may receive a “password reset” notification but many users dismiss these as spam or may not notice.
Impact Assessment
Account takeover on GitLab has cascading consequences:
- Source code access: All repositories the compromised account has access to are readable (and writable for developer/admin accounts).
- CI/CD pipeline manipulation: Attackers can modify pipeline configurations to inject malicious code into build processes or deployment scripts.
- Secret exfiltration: CI/CD variables, environment secrets, API tokens, and cloud credentials stored in GitLab are accessible.
- Supply chain risk: For GitLab instances used by software vendors, compromised pipelines can inject malicious code into distributed software.
- Admin account takeover: Administrators can access all repositories, user accounts, and instance-level settings — effectively complete instance compromise.
Affected Versions
| Product | Affected Versions | Fixed Version |
|---|---|---|
| GitLab CE/EE | 16.1.0 – 16.1.5 | 16.1.6+ |
| GitLab CE/EE | 16.2.0 – 16.2.8 | 16.2.9+ |
| GitLab CE/EE | 16.3.0 – 16.3.6 | 16.3.7+ |
| GitLab CE/EE | 16.4.0 – 16.4.4 | 16.4.5+ |
| GitLab CE/EE | 16.5.0 – 16.5.5 | 16.5.6+ |
| GitLab CE/EE | 16.6.0 – 16.6.3 | 16.6.4+ |
| GitLab CE/EE | 16.7.0 – 16.7.1 | 16.7.2+ |
GitLab.com (SaaS) was patched before the advisory.
Remediation Steps
-
Upgrade GitLab: Apply the fixed version for your branch. This is the only complete remediation.
-
Enable 2FA for all users (critical interim measure): While 2FA doesn’t fully prevent token delivery to the attacker’s email, it prevents account takeover for accounts with 2FA enabled:
# Admin Area > Settings > Sign-in Restrictions Enable: "Require all users to set up two-factor authentication" -
Audit recent password resets: Review GitLab application logs for password reset events, particularly any resets of administrator accounts:
# GitLab application log grep "password reset" /var/log/gitlab/gitlab-rails/application.log -
Review administrator account activity: Check all administrator accounts for unexpected login events, repository access, or settings changes.
-
Rotate CI/CD credentials: If administrator or developer accounts may have been compromised, rotate all CI/CD tokens, personal access tokens, and deploy keys.
Detection Guidance
Log sources:
- GitLab Rails application log:
/var/log/gitlab/gitlab-rails/application.log - GitLab auth log:
/var/log/gitlab/gitlab-rails/auth.log - NGINX access log:
/var/log/gitlab/nginx/gitlab_access.log
Detection pattern:
# Look for password reset requests with array-style email parameter
grep "users/password" /var/log/gitlab/nginx/gitlab_access.log | grep "POST"
# Check application log for password reset with multiple emails
grep "password.*reset" /var/log/gitlab/gitlab-rails/application.log
Suricata signature:
alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"GitLab CVE-2023-7028 Password Reset Array Injection"; flow:established,to_server; http.uri; content:"/users/password"; http.request_body; content:"user[email][]"; sid:9002370; rev:1;)
Timeline
| Date | Event |
|---|---|
| November 2023 | Vulnerability reported to GitLab |
| January 11, 2024 | GitLab publishes advisory; patches released |
| January 12, 2024 | PoC exploit published publicly |
| May 1, 2024 | CISA adds CVE-2023-7028 to KEV catalogue (confirmed exploitation) |
| May 2024 | Security firms document exploitation campaigns |