HexBrain

curl · Report #2764830

CVE-2024-9681: HSTS subdomain overwrites parent cache entry

Validstatus
lowseverity
49upvotes
6 Nov 2024disclosed

How it was found

Summary:

Suppose my HSTS cache file has the following content:

.domain.com "20241107 01:02:03"
.sub.domain.com "unlimited"

Now, I connect to https://sub.domain.com/. Suppose this domain now sets a HSTS policy: Strict-Transport-Security: max-age=15768000 ; includeSubDomains. Surprisingly my HSTS cache file now becomes:

.domain.com "unlimited"
.sub.domain.com "20250408 00:26:19"

While the HSTS policy for "sub.domain.com" is correctly updated, the HSTS expiration time for "domain.com" is mistakenly set to be the previous expiration time for "sub.domain.com".

If I have multiple levels of subdomains in my HSTS cache, the situation is more confusing. Suppose my HSTS cache is:

.com "20241108 01:02:03"
.badssl.com "20260408 04:39:00"

Now I connect to https://hsts.badssl.com/index.html. After that, the HSTS cache becomes:

.com "20260408 04:39:00"
.hsts.badssl.com "20250408 04:49:30"

Steps To Reproduce:

  • curl version: curl 8.11.0-DEV (x86_64-pc-linux-gnu) libcurl/8.11.0-DEV OpenSSL/3.0.2 libpsl/0.21.0, curl source HEAD commit: 86d5c2651d3ea8af316eff2a2452ae61413c66ba

  • Also reproducible in curl 8.10.1 release version.

    1. Create a text file testhsts.txt with the following content: .badssl.com "20241101 00:25:31" (less than 1 month expiration time)
    2. Run curl -v --hsts ./testhsts.txt "http://hsts.badssl.com/index.html". Check the content of testhsts.txt
    3. Run curl -v --hsts ./testhsts.txt "http://hsts.badssl.com/index.html" again. Check the content of testhsts.txt again.
  • After step 2, the content of testhsts.txt is:

.badssl.com "20241101 00:25:31"
.hsts.badssl.com "20250408 04:39:00"
  • After step 3, the content of testhsts.txt is:
.badssl.com "20250408 04:39:00"
.hsts.badssl.com "20250408 04:40:01"

You can see the expiration time of .badssl.com is set incorrectly.

Supporting Material/References:

None

Impact

For shared subdomains, i.e. different subdomains are controlled by different users, a malicious subdomain can influence the HSTS expiration time of the parent domain. By my tests, a subdomain can only increase the expiration time of its parent domain, but can't shorten it. A malicious subdomain can cause a denial of service of its parent domain, if the parent domain only plans to support HSTS for a short period of time, and wants to revert to plaintext http after a while. By exploiting this bug, the malicious subdomain can set a very long max-age for itself, and this bug can cause curl to overwrite the parent domain's HSTS expiration time to be very long.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original