HexBrain

curl · Report #3609505

HSTS accepted from HTTP origin behind HTTPS proxy

Informativestatus
25upvotes
17 Mar 2026disclosed

How it was found

curl/libcurl appears to accept and persist Strict-Transport-Security from an http:// origin when the request is sent through an https:// proxy. After that, a later http:// request for the same host is automatically upgraded to https:// due to stored HSTS state.

Affected versions

8.12.0 through 8.19.0

This appears to be introduced by commit 25b445e https://github.com/curl/curl/commit/25b445e4796bcbf9f842de686a8c384b30f6c2a2

As a side effect of that broad switch from handler-based SSL checks to connection-based SSL checks, the HSTS gate now passes for plain http:// requests sent over an HTTPS proxy because the first connection hop is TLS.

Reproduction

First request:

curl -v \
  --proxy https://127.0.0.1:18443 --proxy-insecure \
  --hsts ./hsts-cache.txt \
  http://hsts-probe.test:18080/

origin replied with Strict-Transport-Security: max-age=31536000 curl stored an HSTS entry for hsts-probe.test

Second request with the same HSTS file:

curl -v \
  --proxy https://127.0.0.1:18443 --proxy-insecure \
  --hsts ./hsts-cache.txt \
  http://hsts-probe.test:18080/

curl printed: Switched from HTTP to HTTPS due to HSTS => https://hsts-probe.test:18080/ curl then sent CONNECT hsts-probe.test:18080 HTTP/1.1 to the proxy

I can provide a minimal test script if needed.

Expected behavior

An http:// origin response should not be able to set HSTS just because the proxy connection is HTTPS. Proxy TLS should not be treated as origin HTTPS for HSTS learning.

Impact

Persistent HSTS state can be learned for a host from an http:// origin when that origin is accessed through an https:// proxy, causing later http:// requests for that host to be automatically upgraded to https://

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