CVE-2022-1423
Description
Improper access control in the CI/CD cache mechanism in GitLab CE/EE affecting all versions starting from 1.0.2 before 14.8.6, all versions from 14.9.0 before 14.9.4, and all versions from 14.10.0 before 14.10.1 allows a malicious actor with Developer privileges to perform cache poisoning leading to arbitrary code execution in protected branches
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Developer-level users could poison the CI/CD cache in GitLab, leading to arbitrary code execution on protected branches.
Vulnerability
GitLab CE/EE versions 1.0.2 up to 14.8.6, 14.9.0 to 14.9.4, and 14.10.0 to 14.10.1 improperly isolate the CI/CD cache for protected branches. The cache key does not incorporate branch protection status, allowing pipelines on non-protected branches to share the same cache key as protected branches [1]. A malicious user with Developer privileges can poison this shared cache by placing a malicious artifact (e.g., a backdoored binary) in the cache key used by a protected branch's pipeline [1].
Exploitation
The attacker needs Developer role on the target project, which allows creating pipelines on a non-protected branch. The attacker creates a .gitlab-ci.yml that uploads a malicious file to the cache with a specific key that matches the key a protected branch pipeline would use (e.g., $CI_JOB_NAME-$CI_COMMIT_REF_SLUG) [1]. When the next pipeline runs on a protected branch (e.g., master) with the same job name and same ref slug, GitLab reuses the poisoned cache instead of rebuilding dependencies [1]. No additional authentication or user interaction is required beyond the developer creating the pipeline.
Impact
Successful exploitation allows code execution in the context of the protected branch's CI/CD job. This means the attacker's malicious payload runs with the privileges of the protected branch pipeline, which may have access to deployment credentials, production secrets, or the ability to alter the final build artifact deployed to production [1]. The outcome is arbitrary code execution and potential full compromise of the CI/CD pipeline and its downstream environments.
Mitigation
GitLab fixed this vulnerability in versions 14.8.6, 14.9.4, and 14.10.1 released on 2022-05-19 [1]. Users should upgrade to one of these patched versions. There is no workaround disclosed; if upgrade is not immediately possible, restricting developer access to the project can reduce risk, but does not eliminate the vulnerability entirely. This issue is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog as of this writing.
AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
3- Range: <14.8.6, >=14.9.0 <14.9.4, >=14.10.0 <14.10.1
- Range: >=1.0.2, <14.8.6
Patches
0No patches discovered yet.
Vulnerability mechanics
Root cause
"Missing isolation of CI/CD cache keys between protected and unprotected branches allows cache poisoning."
Attack vector
An attacker with Developer privileges (or any permission allowing pipeline execution on an unprotected branch) can poison the cache used by a protected branch. The attacker creates a branch (e.g., `feature/cache-poisoning`) and crafts a `.gitlab-ci.yml` that uses a cache key matching the protected branch's cache key (e.g., `test-master`). When the attacker's pipeline runs, it overwrites cached artifacts (e.g., a binary or library) with malicious content. A subsequent pipeline on the protected branch (e.g., `master`) reuses the poisoned cache, executing the attacker's code in the protected branch's context [ref_id=1].
Affected code
The CI/CD cache mechanism in GitLab CE/EE does not isolate cache keys based on the protected status of the branch. The cache key is constructed from job name and branch ref slug (e.g., `"$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"`), but no prefix or namespace distinguishes protected from unprotected branches [ref_id=1].
What the fix does
The advisory does not include a published patch diff, but the expected fix is to separate cache namespaces for protected and unprotected branches. The reporter recommended forcing a prefix in the cache key that indicates the privilege level of the job, so that jobs on unprotected branches cannot overwrite caches used by protected branches [ref_id=1]. GitLab addressed this in versions 14.8.6, 14.9.4, and 14.10.1 by isolating the cache per branch protection status.
Preconditions
- authAttacker must have Developer privileges or sufficient permissions to push code and trigger a pipeline on an unprotected branch.
- configThe target project must have CI/CD caching enabled with a cache key that can be guessed or derived (e.g., using $CI_JOB_NAME-$CI_COMMIT_REF_SLUG).
- inputThe protected branch must have a pipeline that uses the same cache key as the attacker's branch.
Reproduction
1. Create a GitLab project with a `.gitlab-ci.yml` on the protected `master` branch that uses a cache key like `"$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"` and caches a binary (e.g., `critical_binary`). 2. Run the pipeline on `master` to populate the cache. 3. Create a new unprotected branch (e.g., `feature/cache-poisoning`) with a `.gitlab-ci.yml` that uses the same cache key (e.g., `test-master`) and overwrites the cached binary with malicious content. 4. Run the pipeline on the unprotected branch. 5. Trigger a new pipeline on `master` — it will reuse the poisoned cache and execute the attacker's code [ref_id=1].
Generated on May 24, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
3- gitlab.com/gitlab-org/cves/-/blob/master/2022/CVE-2022-1423.jsonmitrex_refsource_CONFIRM
- gitlab.com/gitlab-org/gitlab/-/issues/330047mitrex_refsource_MISC
- hackerone.com/reports/1182375mitrex_refsource_MISC
News mentions
0No linked articles in our index yet.