CVE-2023-46219: HSTS long file name clears contents
Low
C
curl
Submitted None
Actions:
Reported by
cxshakal
Vulnerability Details
Technical details and impact analysis
## Summary:
I've discovered a significant security flaw in cURL's file handling, particularly affecting the HSTS (HTTP Strict Transport Security) database when handling long filenames.
### Vulnerability Description
cURL erroneously creates temporary files with names potentially exceeding the filesystem's maximum filename length (typically 255 bytes for ext4, etc.). If a filename used in the HSTS database is longer than 243 bytes (255 bytes minus 9 for the random suffix and 4 for the '.tmp' extension), an unexpected security error occurs, leading to the HSTS database being overwritten.
### Affected Code
**File: curl/lib/fopen.c**
```c
CURLcode Curl_fopen(struct Curl_easy *data, const char *filename, FILE **fh, char **tempname) {
CURLcode result = CURLE_WRITE_ERROR;
unsigned char randsuffix[9]; // Random suffix generation <=======
...
tempstore = aprintf("%s.%s.tmp", filename, randsuffix); // Temporary filename creation <=======
if(!tempstore) {
result = CURLE_OUT_OF_MEMORY;
goto fail;
}
}
```
**File: curl/lib/hsts.c**
```c
result = Curl_fopen(data, file, &out, &tempstore);
...
if(!result && tempstore && Curl_rename(tempstore, file)) // Attempt to rename temp file to actual file <======
result = CURLE_WRITE_ERROR;
if(result && tempstore)
unlink(tempstore); // Remove temp file if error occurs
```
## Steps To Reproduce:
First let’s check the correct behaviour. I’ve created simple hsts file for cxsecurity.com domain
```bash
$ cat ok.hsts.txt
# Your HSTS cache. https://curl.se/docs/hsts.html
# This file was generated by libcurl! Edit at your own risk.
cxsecurity.com "20241031 12:12:12"
$ curl --hsts ok.hsts.txt http://cxsecurity.com -v
* Switched from HTTP to HTTPS due to HSTS => https://cxsecurity.com/
* Trying 188.114.97.1:443...
…
```
So works great. Let’s try update the database and add Facebook
```bash
$ curl --hsts ok.hsts.txt https://facebook.com -v
* Trying 31…
* Connected to facebook.com …
…
< Strict-Transport-Security: max-age=15552000; preload
…
$ cat ok.hsts.txt
# Your HSTS cache. https://curl.se/docs/hsts.html
# This file was generated by libcurl! Edit at your own risk.
cxsecurity.com "20241031 12:12:12"
facebook.com "20240430 00:11:44"
```
The file has been successfully updated.
Let’s see what will happen if the user will define filename longer that 243 (let’s use the content from previous file)
```bash
$ cp ok.hsts.txt hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.txt
```
Let’s validate the file size as it will be important to prove security issue.
```bash
$ ls -la hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.txt
-rw-r--r-- 1 cx cx 179 Nov 1 19:14 hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.txt
```
we have 179 bytes.
If the user will use such file, curl will reset the content due to improper rename action
```bash
$ cat hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.txt
# Your HSTS cache. https://curl.se/docs/hsts.html
# This file was generated by libcurl! Edit at your own risk.
cxsecurity.com "20241031 12:12:12"
facebook.com "20240430 00:11:44"
$ curl --hsts hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.txt https://facebook.com -v
* Trying …
* Connected to facebook.com …
…
```
Let’s check the file size again..
```bash
$ ls -la hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.txt
-rw-r--r-- 1 cx cx 0 Nov 1 19:17 hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.hsts.txt
```
Now the HSTS database is empty!
## Tested on
#curl 8.4.1-DEV (Linux) libcurl/8.4.1-DEV OpenSSL/3.0.10 zlib/1.2.13
## Possible solutions:
- Check the max length of supported file and create shortcut eg by using “~”
- Create random short file name at /tmp/
I believe addressing this vulnerability is crucial for maintaining the integrity of the HSTS database in cURL, and I'm keen to assist in any way possible to resolve this issue. Looking forward to your response.
## Impact
Bypass HSTS
Report Details
Additional information and metadata
State
Closed
Substate
Resolved
Submitted
Weakness
Missing Encryption of Sensitive Data