# Bypass of GitLab CI runner slash fix in YAML validation

GitLab CI cache key validation could be bypassed via a CI/CD variable, allowing path traversal to poison another project's cache and run arbitrary code.

- Payout: hidden
- Severity: critical
- Program: GitLab
- Found by: ngalog
- Disclosed: 2019-04-10
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/409395
- Library page: https://bugbountylibrary.com/r/h1%3A409395
- Tags: area:web domain:web impact:integrity impact:rce kind:bounty platform:hackerone sev:critical tech:ci-cd technique:incomplete-fix vuln:path-traversal vuln:rce

**Target:** GitLab CI runner cache key / YAML validation
**Root cause:** The fix for the cache key path traversal was enforced only during YAML validation of the literal key, so a key referencing a CI/CD variable ($ONE) bypassed normalization and resolved to a traversal path at runtime.
**Steps:**
1. Set CI/CD variable `ONE` to `../1/key` in project settings (Settings > CI/CD).
2. In `.gitlab-ci.yml`, define a job with `cache: key: "$ONE"`, `policy: pull` (or push), `paths: [.]`.
3. Trigger a pipeline by changing `.gitlab-ci.yml`; the runner resolves the key to a traversal path and downloads/uploads cache outside the project's namespace.
**How found:** Noticed the prior fix (#301432) only validated the literal YAML cache key, hypothesized that variable interpolation happens after validation, and tested by setting the key via a CI/CD variable.
**Exploitation:** Attacker sets a variable to a traversal value and uses it as the cache key with push policy to write a poisoned cache into another project's cache namespace; a victim pipeline with pull policy then downloads the attacker-controlled cache contents, enabling arbitrary code execution in the victim's CI Docker instance.
**Escalation:** Cache poisoning crosses project boundaries, letting an attacker inject artifacts/code into another project's build pipeline.
**Insight:** When a fix validates a value at config-parse time, check whether that value supports variable interpolation or other late binding that resolves after the check.

