# CVE-2020-8177: curl overwrite local file with -J

curl's -OJi flag combination bypasses the existing-file check, letting a malicious server overwrite arbitrary local files like .bashrc via Content-disposition filename.

- Payout: hidden
- Severity: medium
- Program: curl
- Found by: snsn
- Disclosed: 2020-12-05
- CVE: CVE-2020-8177
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/887462
- Library page: https://bugbountylibrary.com/r/h1%3A887462
- Tags: area:oss domain:oss impact:integrity impact:rce kind:bounty platform:hackerone sev:medium tech:curl technique:incomplete-fix technique:source-review vuln:file-upload vuln:rce

**Target:** curl CLI tool (tool_cb_hdr.c / tool_cb_wrt.c)
**Root cause:** The -i and -J option conflict check only rejects '-iJ' order, not '-Ji'; and the header-callback write path (tool_cb_hdr.c) opens the Content-disposition filename without the existing-file verification present in tool_cb_wrt.c.
**Steps:**
1. Serve HTTP response with body `<PAYLOAD>` (e.g. `echo pwn`) and header `Content-disposition: attachment; filename=".bashrc"`
2. Run `curl -OJi <url>` from the user's home directory
3. curl writes response headers+body into `.bashrc`, overwriting it despite warning that overwrite was refused
**How found:** Code review of option parsing found the -i/-J conflict check is order-sensitive (only blocks -iJ, not -Ji); tracing the -OJi flow showed the header callback opens the filename without the existing-file guard used in tool_cb_wrt.c.
**Exploitation:** Attacker controls a server the victim curls with -OJi; the Content-disposition filename is opened via the header callback path without existence check, so the response (including attacker payload) is written over a chosen local file such as .bashrc, yielding code execution on next shell start.
**Escalation:** Overwriting shell rc files like .bashrc turns file overwrite into logical RCE when curl is run from home dir.
**Insight:** Order-sensitive option-conflict checks are a recurring bug pattern: test both argument orders. Also compare parallel code paths (header callback vs write callback) for missing guards present in one but not the other.

