CVE-2020-8177: curl -J + -i local file overwrite via header-callback file creation bypass
a4913a9f-61dd-413a-b71d-48e946d92fa6
CVE-2020-8177 (curl 7.20.0 — 7.70.0). When a victim runs curl -OJi http://attacker/path (or any combination that sets both -J / --remote-header-name and -i / --include), a malicious HTTP server can silently overwrite an arbitrary file in the user's filesystem named after the URL's last path component. The -J option is supposed to refuse to clobber existing files; -i defeats that protection because it forces the output stream to be created before any Content-Disposition is parsed, and the early creation path leaves outs->is_cd_filename = FALSE — which is exactly the flag tool_create_output_file() keys its overwrite check on. Attack class: symlink/local-file-overwrite from a remote server (no local privileges required).
grep -rn "content-disposition" src/ pinned the logic to src/tool_cb_hdr.c and src/tool_cfgable.h. 3. Read tool_header_cb in src/tool_cb_hdr.c (lines 56-230). The Content-Disposition block (158-207) sets outs->is_cd_filename=TRUE before tool_create_output_file. The trailing show_headers block (209-228) calls tool_create_output_file at line 215 WITHOUT setting is_cd_filename. 4. Read tool_create_output_file in src/tool_cb_wrt.c (lines 36-73): the if(file=fopen(...,"rb")) overwrite-protection guard is inside if(outs->is_cd_filename) — so the show_headers path bypasses it and goes straight to fopen("wb"), truncating any existing file. 5. grep -n "honor_cd_filename\\|show_headers\\|content_disposition" src/tool_*.c showed the 7.71.0 fix lives in src/tool_getparam.c case 'i' (lines 1819-1827) and case 'J' (lines 1839-1846): both reject the combination with PARAM_BAD_USE. 6. Confirmed two additional bypass paths still latent: tool_cb_hdr.c line 205 (Content-Disposition with no filename= falls through and creates the URL-derived file without is_cd_filename), and tool_cb_wrt.c line 153 (body data before any header callback creates file without is_cd_filename).