Description
## Executive Summary
`Curl_fopen()` clones the permissions of any pre-existing persistence file when creating its temporary file. When the persistence file does not exist, it first creates one with the process umask (typically `022`, i.e., `0644`). That mode is then copied to the temp file via `0600` | `sb.st_mode`, so the final cookie/HSTS/Alt-Svc store ends up group/other-readable even though it contains bearer tokens. (`lib/curl_fopen.c:101-150`)
All stateful persistence features that rely on `Curl_fopen()`—`cookie_output()`, `Curl_hsts_save()`, and `Curl_altsvc_save()`—inherit this behavior, leaking session cookies, HSTS cache entries, and Alt-Svc metadata to any local user.
## Steps To Reproduce
Environment: `macOS 26.1 Dev Beta 4`, `commit a49e4e3d16991465144558f405b2d7972824abb0`, built with `./configure --disable-shared --with-openssl=/opt/homebrew/opt/openssl@3 --without-libpsl && make -j8`.
1. Ensure no leftover file and simulate a normal multi-user umask:
```
rm -f /tmp/cookie-leak.txt && umask 022 \
&& ./src/curl -s -o /dev/null -c /tmp/cookie-leak.txt https://example.org \
&& ls -l /tmp/cookie-leak.txt
.rw-r--r-- 131 geeknik 26 Oct 22:22 /tmp/cookie-leak.txt
```
{F4935751}
The cookie jar is created even though no cookies were set, which is enough to demonstrate the default mode of `0644`.
2. As another local user simply `cat /tmp/cookie-leak.txt`, read the file contents—full session cookies would be exposed in real traffic. The same reproduction works for `--hsts` and `--alt-svc` files because they call `Curl_fopen()` with identical code paths.
Additionally, we were able to reproduce this behavior on Fedora with `curl 8.6.0` (x86_64-redhat-linux-gnu).
## CVSS v3.0
AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
## Suggested Fix
Replace [lines 140-141](https://github.com/curl/curl/blob/a49e4e3d16991465144558f405b2d7972824abb0/lib/curl_fopen.c#L140) with:
```c
fd = curlx_open(tempstore, O_WRONLY | O_CREAT | O_EXCL, 0600);
```
## Impact
Any local user on the same host (shared CI runners, university shells, managed desktops, etc.) can read authentication cookies, session tokens, CSRF nonces, HSTS preload data, or Alt-Svc targets written by another user’s curl/libcurl client. Immediate consequences range from full account takeover (cookie replay) to bypassing HSTS (by rewriting the file before the victim reads it) and intelligence gathering on internal endpoints listed in Alt-Svc caches. Because the files are written automatically whenever `CURLOPT_COOKIEJAR`, `CURLOPT_HSTSWRITEFUNCTION`, or `CURLOPT_ALTSVC` are used, even well-configured automation unintentionally leaks secrets to co-resident users.
`Curl_fopen()` clones the permissions of any pre-existing persistence file when creating its temporary file. When the persistence file does not exist, it first creates one with the process umask (typically `022`, i.e., `0644`). That mode is then copied to the temp file via `0600` | `sb.st_mode`, so the final cookie/HSTS/Alt-Svc store ends up group/other-readable even though it contains bearer tokens. (`lib/curl_fopen.c:101-150`)
All stateful persistence features that rely on `Curl_fopen()`—`cookie_output()`, `Curl_hsts_save()`, and `Curl_altsvc_save()`—inherit this behavior, leaking session cookies, HSTS cache entries, and Alt-Svc metadata to any local user.
## Steps To Reproduce
Environment: `macOS 26.1 Dev Beta 4`, `commit a49e4e3d16991465144558f405b2d7972824abb0`, built with `./configure --disable-shared --with-openssl=/opt/homebrew/opt/openssl@3 --without-libpsl && make -j8`.
1. Ensure no leftover file and simulate a normal multi-user umask:
```
rm -f /tmp/cookie-leak.txt && umask 022 \
&& ./src/curl -s -o /dev/null -c /tmp/cookie-leak.txt https://example.org \
&& ls -l /tmp/cookie-leak.txt
.rw-r--r-- 131 geeknik 26 Oct 22:22 /tmp/cookie-leak.txt
```
{F4935751}
The cookie jar is created even though no cookies were set, which is enough to demonstrate the default mode of `0644`.
2. As another local user simply `cat /tmp/cookie-leak.txt`, read the file contents—full session cookies would be exposed in real traffic. The same reproduction works for `--hsts` and `--alt-svc` files because they call `Curl_fopen()` with identical code paths.
Additionally, we were able to reproduce this behavior on Fedora with `curl 8.6.0` (x86_64-redhat-linux-gnu).
## CVSS v3.0
AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
## Suggested Fix
Replace [lines 140-141](https://github.com/curl/curl/blob/a49e4e3d16991465144558f405b2d7972824abb0/lib/curl_fopen.c#L140) with:
```c
fd = curlx_open(tempstore, O_WRONLY | O_CREAT | O_EXCL, 0600);
```
## Impact
Any local user on the same host (shared CI runners, university shells, managed desktops, etc.) can read authentication cookies, session tokens, CSRF nonces, HSTS preload data, or Alt-Svc targets written by another user’s curl/libcurl client. Immediate consequences range from full account takeover (cookie replay) to bypassing HSTS (by rewriting the file before the victim reads it) and intelligence gathering on internal endpoints listed in Alt-Svc caches. Because the files are written automatically whenever `CURLOPT_COOKIEJAR`, `CURLOPT_HSTSWRITEFUNCTION`, or `CURLOPT_ALTSVC` are used, even well-configured automation unintentionally leaks secrets to co-resident users.
Basic Information
ID
H1:3400761
Published
Oct 27, 2025 at 04:09
Modified
Oct 28, 2025 at 07:09