✓ProveIt
Examples / Report #1573634 Saved analysis

CVE-2022-32207: Unpreserved file permissions

curl · 2022-05-1714.7s analysis · $0.011 in model calls

What the report claims

Curl fails to preserve file permissions when writing CURLOPT_COOKIEJAR, CURLOPT_ALTSVC, and CURLOPT_HSTS databases, resetting permissions to 0666 & ~umask and potentially overwriting symlinks or special files, leading to information leaks and system damage.

Compare with curl's recorded outcome

Known vulnerability

A real vulnerability: CVE-2022-32207 Non-preserved file permissions

Shown for comparison after analysis. The pipeline did not see this label.

ProveIt's finding

Needs human review

The available evidence does not settle the report. A maintainer should investigate.

Why this finding?
  • The central claim (C1) about failure to preserve file permissions cannot be verified because the provided curl_source lacks the actual database writing implementation for CURLOPT_COOKIEJAR, CURLOPT_ALTSVC, and CURLOPT_HSTS.
  • The reproduction steps and impact claims depend on code paths not shown in the provided source snippets (only CMakeLists.txt, curl_setup.h, memdebug.h are provided).
  • The report is specific and plausible, citing a concrete commit and issue number, but the evidence needed to confirm or refute it is not in the provided context.
  • A human maintainer should examine the cookie jar, altsvc, and hsts file-writing code (likely in lib/cookie.c, lib/hsts.c, or similar) at the relevant revision.
What still needs checking
  • Source code for the functions that write CURLOPT_COOKIEJAR, CURLOPT_ALTSVC, and CURLOPT_HSTS databases (e.g., cookie_jar_write, hsts_save, altsvc_save)
  • The commit b834890a3fa3f525cd8ef4e99554cdb4558d7e1b diff or the code it changed
  • File opening/renaming logic that would show permission handling and symlink behavior
How this analysis ran 6 claims · 0 citations verified

Checked against curl master on 2022-05-17 (0842936292f9). Dev evaluation split. Citation verification checks that a referenced line was in the evidence; it does not prove the model interpreted it correctly.

1 · Grounding
partially grounded
no model · 5 references checked out, 2 did not
2 · Claims
NVIDIA-Nemotron-3-Nano-30B-A3B
6 claims · 2219 tokens · $0.0003
3 · Evidence
4 code snippets
real curl source at 0842936292f9 · 4 docs via Tavily
4 · Judgment
Nemotron-3-Ultra-550b-a55b
6573 tokens · 11.5s · $0.0112
5 · Receipts
0 of 0 citations verified
every citation must point at code the judge was shown
Review a draft reply to the reporter

Edit and verify before sending.

Thank you for the detailed report. The provided code snippets do not include the cookie jar, altsvc, or hsts database writing logic, so we cannot verify the permission preservation behavior from this context alone. Could you point to the specific source files and functions (e.g., in lib/cookie.c, lib/hsts.c) where these databases are written? That would allow us to check the file permission handling and symlink/special-file behavior you describe.

Inspect all claims and source code 6 claims · 4 code excerpts

Report claims

C1flaw not verifiable

curl fails to preserve file permissions when writing CURLOPT_COOKIEJAR, CURLOPT_ALTSVC, and CURLOPT_HSTS databases

Read the reasoning

The provided curl_source does not contain the implementation code for writing CURLOPT_COOKIEJAR, CURLOPT_ALTSVC, or CURLOPT_HSTS databases. Only CMakeLists.txt, curl_setup.h, and memdebug.h are shown, which define build configuration and header macros but not the database writing logic. Without the actual file-writing code, I cannot verify whether permissions are preserved.

C2location not verifiable

the vulnerability was introduced in commit b834890a3fa3f525cd8ef4e99554cdb4558d7e1b

Read the reasoning

The external source E1 (RFC 4914 references) does not mention commit b834890a3fa3f525cd8ef4e99554cdb4558d7e1b or curl issue #4914. The deterministic checks note only 2/12 quoted lines appear in curl at the checked revision, but the relevant commit diff is not provided.

C3trigger not verifiable

using umask 022 and creating a cookie.db file with permissions 600 before curl accesses it

Read the reasoning

This describes a reproduction scenario, not code behavior. The code path that would handle this scenario is not in the provided source.

C4impact not verifiable

a file that was previously protected becomes readable by other users and symlinks may be replaced with malicious databases or special files may be overwritten

Read the reasoning

Impact claims depend on the actual file-writing behavior, which is not shown in the provided source. The symlink replacement and /dev/null overwrite claims require examining the file-opening and renaming logic, which is absent.

C5reproduction not verifiable

steps: set umask 022, create a cookie.db with 600 permissions, run curl with -b and -c pointing to it, then list the file permissions

Read the reasoning

Reproduction steps reference external URL (google.com) and command-line flags (-b, -c). The handling of these flags and the cookie jar writing code is not in the provided source.

C6flaw not verifiable

the fix recommendation suggests checking if the file is a regular file before overwriting and preserving ownership and group

Read the reasoning

This is a fix recommendation, not a claim about current code. The provided source shows S_ISREG macro exists (curl_setup.h:712) and fdopen macro exists (memdebug.h:153), but fchmod is noted as not present at this revision per deterministic checks. The recommendation's code is not in the codebase.

Deterministic checks that failed

  • symbol fchmod exists in other curl releases but not at 0842936292f9
  • quote only 2/12 quoted lines appear anywhere in curl at 0842936292f9

What the report says about other projects

not addressed The vulnerability was introduced in commit b834890a3fa3f525cd8ef4e99554cdb4558d7e1b to fix issue #4914

Read the original report (excerpt)

Full report on HackerOne ↗

## Summary: Curl fails to preserve file permissions when writing: - `CURLOPT_COOKIEJAR` database - `CURLOPT_ALTSVC` database - `CURLOPT_HSTS` database Instead the permissions is always reset to 0666 & ~umask if the file is updated. As a result a file that was before protected against read access by other users becomes other user readable (as long as umask doesn't have bit 2 set). Out of these files only the `CURLOPT_COOKIEJAR` is likely to contain sensitive information. In addition curl will replace softlink to the database with locally written database, or if the application is run privileged, specifying `"/dev/null"` as a file name can lead to system overwriting the special file and result in inoperable system. This is CWE-281: Improper Preservation of Permissions ## Steps To Reproduce: 1. `umask 022` 2. `install -m 600 /dev/null cookie.db` 3. `curl -b cookie.db -c cookie.db https://google.com` 4. `ls -l cookie.db` At least for `CURLOPT_COOKIEJAR` this vulnerability was introduced in https://github.com/curl/curl/commit/b834890a3fa3f525cd8ef4e99554cdb4558d7e1b - this change was introduced to fix a issue https://github.com/curl/curl/issues/4914 ## Fix recommendations If a file file is created and moved over a the old one, only do this if the file is regular file. Anything else is likely going to end up causing unexpected behaviour, outright failing, or if the user has high enough permissions, damage to the operating system. Safe cloning of file permissions can only be achieved if the owner / group of the file match the current user (else group permissions might be incorrect). Hence creating a new file and moving it over the old one should IMO only be attempted if the file user and group match that of the previous file. If a method of creating a new file is still desired, something like this could be attempted to cover the most use cases: ``` /* If old file is a regular file attempt creating a new file with same ownership */ struct stat st; if (stat(filename, &st) != -1 && S_ISREG(st.st_mode)) { FILE *file; int fd; struct stat nst; fd = open(tempstore, O_CREAT | O_EXCL, 0700); if (fd == -1) goto fail; if (fstat(fd, &nst) == -1 || nst.st_uid != st.st_uid || nst.st_gid != st.st_gid) { /* newly created file doesn't have same ownership, we can't proceed safely */ close(fd); unli …

Source code

lib/CMakeLists.txtlines 133–143 · definition of install
133install(TARGETS ${LIB_NAME}
134 EXPORT ${TARGETS_EXPORT_NAME}
135 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
136 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
137 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
138)
139
140export(TARGETS ${LIB_NAME}
141 APPEND FILE ${PROJECT_BINARY_DIR}/libcurl-target.cmake
142 NAMESPACE ${PROJECT_NAME}::
143)
lib/curl_setup.hlines 329–329 · definition of stat
329# define stat(fname,stp) curlx_win32_stat(fname, stp)
lib/curl_setup.hlines 712–712 · definition of S_ISREG
Show 1 lines (not cited by the judge)
712#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
lib/memdebug.hlines 153–153 · definition of fdopen
Show 1 lines (not cited by the judge)
153#define fdopen(file,mode) curl_dbg_fdopen(file,mode,__LINE__,__FILE__)