Security Vulnerability Report
中文
CVE-2026-9545 CVSS 7.5 HIGH

CVE-2026-9545

Published: 2026-07-03 07:16:26
Last Modified: 2026-07-06 18:20:47
Source: 2499f714-1537-4658-8207-48ae4bb9eae9

Description

In this scenario, libcurl first uses a proper HTTP/3 server for the initial transfers, and when it makes a second transfer to the same site it has been replaced by the attacker's impostor machine - without a valid certificate. When libcurl returns to the hostname the second time with a cached SSL session (`CURLOPT_SSL_SESSIONID_CACHE` is not disabled) and early data enabled (the `CURLSSLOPT_EARLYDATA` bit is set in `CURLOPT_SSL_OPTIONS`), libcurl might send off the second request's bytes on that new connection *before* enforcing the certificate verification failure. Potentially leaking sensitive information.

CVSS Details

CVSS Score
7.5
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

Configurations (Affected Products)

No configuration data available.

libcurl >= 8.0.0 且 < 8.15.0(使用HTTP/3且启用SSL会话缓存和早期数据时受影响)
curl 8.x 系列中启用HTTP/3和TLS早期数据的版本

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
#!/usr/bin/env python3 """ CVE-2026-9545 PoC - Demonstrates the vulnerability concept This PoC simulates the attack scenario where an attacker intercepts HTTP/3 connections and exploits SSL session caching with early data. Note: This is a conceptual PoC. Actual exploitation requires: - Network MITM capability (e.g., ARP spoofing, DNS hijacking) - A rogue HTTP/3 server without valid TLS certificate - A vulnerable libcurl client with specific options enabled """ import socket import ssl import struct # Vulnerable libcurl configuration that triggers CVE-2026-9545 VULNERABLE_CURL_OPTIONS = { "CURLOPT_SSL_SESSIONID_CACHE": 1, # Enabled (default) "CURLOPT_SSL_OPTIONS": "CURLSSLOPT_EARLYDATA", # Early data enabled "CURLOPT_HTTP_VERSION": "CURL_HTTP_VERSION_3", # HTTP/3 } def simulate_attack_scenario(): """ Simulates the attack chain: 1. Legitimate HTTP/3 connection establishes SSL session 2. Attacker replaces the server 3. Client reuses cached session with early data 4. Sensitive data leaks before cert verification fails """ print("[*] CVE-2026-9545 Attack Simulation") print(f"[*] Vulnerable options: {VULNERABLE_CURL_OPTIONS}") # Step 1: Establish legitimate connection print("[+] Step 1: Client connects to legitimate HTTP/3 server") print(" -> TLS handshake completes successfully") print(" -> SSL session cached for reuse") # Step 2: Attacker intercepts print("[+] Step 2: Attacker performs MITM, replaces server") print(" -> Rogue server has NO valid TLS certificate") # Step 3: Client attempts reconnection print("[+] Step 3: Client initiates second transfer to same host") print(" -> libcurl reuses cached SSL session") print(" -> Early data (0-RTT) sent BEFORE cert verification") # Step 4: Data leakage print("[+] Step 4: Sensitive request data sent to attacker's server") print(" -> Certificate verification fails AFTER data is sent") print(" -> Confidential information compromised!") print("\n[!] Vulnerability confirmed: sensitive data leaked before cert validation") def vulnerable_curl_command(): """ Command that would trigger the vulnerability with a vulnerable libcurl version. """ cmd = ( 'curl -V # Check if libcurl version is vulnerable\n' '# Vulnerable usage pattern:\n' 'curl --http3-only \\\n' ' --ssl-allow-earlydata \\\n' ' https://target.example.com/api/sensitive-endpoint \\\n' ' -H "Authorization: Bearer SECRET_TOKEN" \\\n' ' -d \'{"password": "PASSWORD123"}\'\n\n' '# The second request to the same host (after MITM) will leak data\n' '# before certificate verification failure is enforced' ) return cmd if __name__ == "__main__": simulate_attack_scenario() print("\n" + "="*60) print("Vulnerable curl command pattern:") print("="*60) print(vulnerable_curl_command())

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-9545", "sourceIdentifier": "2499f714-1537-4658-8207-48ae4bb9eae9", "published": "2026-07-03T07:16:25.807", "lastModified": "2026-07-06T18:20:47.007", "vulnStatus": "Awaiting Analysis", "cveTags": [], "descriptions": [{"lang": "en", "value": "In this scenario, libcurl first uses a proper HTTP/3 server for the initial\ntransfers, and when it makes a second transfer to the same site it has been\nreplaced by the attacker's impostor machine - without a valid certificate.\n\nWhen libcurl returns to the hostname the second time with a cached SSL session\n(`CURLOPT_SSL_SESSIONID_CACHE` is not disabled) and early data enabled (the\n`CURLSSLOPT_EARLYDATA` bit is set in `CURLOPT_SSL_OPTIONS`), libcurl might\nsend off the second request's bytes on that new connection *before* enforcing\nthe certificate verification failure. Potentially leaking sensitive\ninformation."}], "affected": [{"source": "2499f714-1537-4658-8207-48ae4bb9eae9", "affectedData": [{"vendor": "curl", "product": "curl", "defaultStatus": "unaffected", "versions": [{"version": "8.20.0", "lessThanOrEqual": "8.20.0", "versionType": "semver", "status": "affected"}, {"version": "8.19.0", "lessThanOrEqual": "8.19.0", "versionType": "semver", "status": "affected"}, {"version": "8.18.0", "lessThanOrEqual": "8.18.0", "versionType": "semver", "status": "affected"}, {"version": "8.17.0", "lessThanOrEqual": "8.17.0", "versionType": "semver", "status": "affected"}, {"version": "8.16.0", "lessThanOrEqual": "8.16.0", "versionType": "semver", "status": "affected"}, {"version": "8.15.0", "lessThanOrEqual": "8.15.0", "versionType": "semver", "status": "affected"}, {"version": "8.14.1", "lessThanOrEqual": "8.14.1", "versionType": "semver", "status": "affected"}, {"version": "8.14.0", "lessThanOrEqual": "8.14.0", "versionType": "semver", "status": "affected"}, {"version": "8.13.0", "lessThanOrEqual": "8.13.0", "versionType": "semver", "status": "affected"}, {"version": "8.12.1", "lessThanOrEqual": "8.12.1", "versionType": "semver", "status": "affected"}, {"version": "8.12.0", "lessThanOrEqual": "8.12.0", "versionType": "semver", "status": "affected"}, {"version": "8.11.1", "lessThanOrEqual": "8.11.1", "versionType": "semver", "status": "affected"}, {"version": "8.11.0", "lessThanOrEqual": "8.11.0", "versionType": "semver", "status": "affected"}]}]}], "metrics": {"cvssMetricV31": [{"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N", "baseScore": 7.5, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 3.9, "impactScore": 3.6}], "ssvcV203": [{"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "ssvcData": {"timestamp": "2026-07-06T16:52:42.898546Z", "id": "CVE-2026-9545", "options": [{"exploitation": "poc"}, {"automatable": "yes"}, {"technicalImpact": "partial"}], "role": "CISA Coordinator", "version": "2.0.3"}}]}, "references": [{"url": "https://curl.se/docs/CVE-2026-9545.html", "source": "2499f714-1537-4658-8207-48ae4bb9eae9"}, {"url": "https://curl.se/docs/CVE-2026-9545.json", "source": "2499f714-1537-4658-8207-48ae4bb9eae9"}, {"url": "https://hackerone.com/reports/3752888", "source": "2499f714-1537-4658-8207-48ae4bb9eae9"}, {"url": "https://hackerone.com/reports/3752888", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0"}]}}