CVE-2026-27448
Medium · 5.3CVSS
5.3
EPSS
0.4%
Published
Mar 18, 2026
CISA due date
—
Cloudanix analysis
Some Python-based encrypted services may accidentally let a connection through when custom hostname-checking code crashes, so affected software should be updated and checked.
- Exploitation
- Remote Unauthenticated
- Attacker needs
- None
- Complexity
- High
- Impact
- Data Tampering
- Component
- Library
- Class
- Authentication Bypass
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Medium
What it actually does
This flaw affects applications using pyOpenSSL versions from 0.14.0 before 26.0.0 when they register a user-defined TLS Server Name Indication callback with set_tlsext_servername_callback. If that callback raises an unhandled exception, pyOpenSSL incorrectly allows the TLS connection to proceed instead of rejecting it. The vulnerability does not create a universal authentication bypass by itself; impact depends on whether the application uses the callback to enforce security decisions such as hostname allowlists, virtual-host isolation, client policy selection, certificate selection, tenant routing, or other access controls. Exploitation requires an attacker to trigger an exception in the callback logic, which is why the attack complexity is high and the practical impact is application-specific.
Why it matters to the business
Organizations using affected pyOpenSSL versions may have services that unintentionally accept TLS connections that should have been denied. If the callback protects access to sensitive endpoints, tenant-specific services, restricted hostnames, or policy-controlled TLS configurations, attackers could bypass intended controls and reach services that operators believed were protected. The current public exploitation signal is low: EPSS is 0.241%, the issue is not listed in CISA KEV, is not known to be used in ransomware campaigns, and no mature public exploit is indicated; however, affected internet-facing services should still be reviewed because the consequence depends on local callback behavior.
How an attack unfolds
An attacker first identifies a TLS service implemented with a vulnerable pyOpenSSL version and using set_tlsext_servername_callback for security-sensitive decision-making. The attacker then studies how the application handles the TLS SNI value or related connection metadata. By sending a specially chosen, malformed, unexpected, empty, oversized, encoded, or otherwise edge-case server name, the attacker attempts to trigger an unhandled exception inside the application-provided callback. In affected pyOpenSSL versions, that exception does not fail closed; instead, the TLS connection is accepted. If the callback was responsible for rejecting unauthorized hostnames or selecting restrictive security policy, the attacker may gain access to a path that should have been blocked. Follow-on impact depends on the service behind the TLS listener and may range from policy bypass to unauthorized access to application functionality.
How to fix it
Upgrade pyOpenSSL to version 26.0.0 or later, where unhandled exceptions in set_tlsext_servername_callback result in rejecting the connection. Because the supplied fixed_versions field is empty, use the upstream advisory version as the minimum fixed version: pyOpenSSL >= 26.0.0. In addition, review all uses of set_tlsext_servername_callback and ensure callback logic fails closed: catch expected exceptions, explicitly reject unsafe or unexpected SNI values, validate input before use, and avoid relying on exception side effects for access control. If immediate upgrade is not possible, add defensive exception handling inside the callback so any error path explicitly denies the connection or applies the most restrictive policy. Consider moving security-critical authorization decisions out of TLS callback logic where feasible, or enforcing them again at the application layer after TLS negotiation.
How to confirm the fix worked
Confirm that all deployed Python environments, containers, virtual environments, and packaged applications use pyOpenSSL 26.0.0 or later. Validate with package inventory commands such as `python -m pip show pyOpenSSL`, dependency lockfiles, SBOMs, container image scans, and runtime introspection where appropriate. Search code for `set_tlsext_servername_callback` and verify whether the callback performs security-sensitive decisions. Test the service with benign malformed or unexpected SNI values in a staging environment and confirm that exceptions or validation failures cause the TLS handshake to fail closed rather than allowing the connection. Review regression tests to ensure callback exceptions are covered and denied by default.
Typical attack path
- Identify a Python TLS service using pyOpenSSL and accepting network connections.
- Determine or infer that the service uses TLS SNI-based callback logic for hostname routing, policy enforcement, access control, or certificate selection.
- Send TLS ClientHello messages with crafted SNI values intended to trigger an exception in the callback code.
- Cause the callback to raise an unhandled exception during TLS negotiation.
- Rely on vulnerable pyOpenSSL behavior that accepts the connection rather than rejecting it.
- Access the service or policy context that the callback was intended to deny or restrict.
- Attempt further application-level interaction using the now-established TLS connection.
How to detect it
To determine whether exploitation may already have occurred, focus on services that both use vulnerable pyOpenSSL versions and implement set_tlsext_servername_callback. Review application logs around TLS handshake handling for unhandled exceptions, tracebacks, or callback errors followed by successful connections from the same source. Correlate TLS access logs, reverse proxy logs, load balancer logs, packet captures, and application authentication logs for connections using unusual, malformed, empty, unexpected, or unauthorized SNI hostnames that were nonetheless accepted. Look for spikes in TLS handshake attempts with varied SNI values, particularly from single sources or scanner infrastructure. If callback exceptions are logged, investigate whether the same client IP subsequently accessed restricted routes, tenant-specific services, administrative interfaces, or hostnames that should have been rejected. Because pyOpenSSL does not provide a universal exploit artifact for this issue, detection is primarily behavioral and application-log dependent.
What your security team should do
- Inventory all services, containers, and Python environments using pyOpenSSL, prioritizing internet-facing TLS services.
- Upgrade pyOpenSSL to 26.0.0 or later wherever present.
- Search codebases for `set_tlsext_servername_callback` and prioritize review of callbacks used for access control, tenant isolation, hostname allowlisting, routing, or certificate/policy selection.
- Add explicit fail-closed exception handling in all TLS SNI callbacks, even after upgrading, to reduce application-layer risk.
- Test affected services with invalid, missing, unexpected, and boundary-case SNI values to confirm connections are rejected when callback logic fails.
- Monitor TLS services for unusual SNI probing, malformed ClientHello activity, repeated handshake anomalies, or access to restricted hostnames.
- Because this issue is not in KEV and has low EPSS with no known mature exploit, prioritize based on exposure and whether the callback enforces security-sensitive behavior rather than treating all installations as equally critical.
The record
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.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| Chainguard | airflow-2 | 0 | 2.11.2-r2 |
| Chainguard | airflow-3 | 0 | 3.1.8-r8 |
| Chainguard | authentik | 0 | 2026.2.1-r4 |
| Chainguard | authentik-fips | 0 | 2026.2.1-r3 |
| Chainguard | awx | 0 | 24.6.1-r31 |
| Chainguard | az | 0 | 2.84.0-r3 |
| Chainguard | datahub-ingestion | 0 | 1.5.0.1-r0 |
| Chainguard | gitlab-toolbox-ce-18.7 | 0 | 18.7.5-r1 |
| Chainguard | gitlab-toolbox-ce-18.8 | 0 | 18.8.5-r2 |
| Chainguard | gitlab-toolbox-ce-18.9 | 0 | 18.9.2-r1 |
| Chainguard | gitlab-toolbox-ce-fips-18.7 | 0 | 18.7.5-r1 |
| Chainguard | gitlab-toolbox-ce-fips-18.8 | 0 | 18.8.5-r1 |
| Chainguard | gitlab-toolbox-ce-fips-18.9 | 0 | 18.9.2-r1 |
| Chainguard | keep-api | 0 | 0.51.0-r0 |
| Chainguard | keep-api-fips | 0 | 0.51.0-r0 |
| Chainguard | localstack | 0 | 4.14.0-r4 |
| Chainguard | py3-cassandra-medusa | 0 | 0.27.0-r5 |
| Chainguard | request-1276 | 0 | 0.27.0-r6 |
| Chainguard | superset-5.0 | 0 | 5.0.0-r20 |
| Chainguard | superset-6.0 | 0 | 6.0.0-r4 |
| SUSE:Linux Enterprise High Performance Computing 15 SP4-ESPOS | python-pyOpenSSL | 0 | 23.2.0-150400.3.13.1 |
| SUSE:Linux Enterprise High Performance Computing 15 SP4-LTSS | python-pyOpenSSL | 0 | 23.2.0-150400.3.13.1 |
| SUSE:Linux Enterprise High Performance Computing 15 SP5-ESPOS | python-pyOpenSSL | 0 | 23.2.0-150400.3.13.1 |
| SUSE:Linux Enterprise High Performance Computing 15 SP5-LTSS | python-pyOpenSSL | 0 | 23.2.0-150400.3.13.1 |
| SUSE:Linux Enterprise Module for Public Cloud 15 SP4 | python-pyOpenSSL | 0 | 23.2.0-150400.3.13.1 |
| SUSE:Linux Enterprise Module for Python 3 15 SP7 | python-pyOpenSSL | 0 | 23.2.0-150400.3.13.1 |
| SUSE:Linux Enterprise Server 15 SP4-LTSS | python-pyOpenSSL | 0 | 23.2.0-150400.3.13.1 |
| SUSE:Linux Enterprise Server 15 SP5-LTSS | python-pyOpenSSL | 0 | 23.2.0-150400.3.13.1 |
| SUSE:Linux Enterprise Server 15 SP6-LTSS | python-pyOpenSSL | 0 | 23.2.0-150400.3.13.1 |
| SUSE:Linux Enterprise Server for SAP Applications 15 SP4 | python-pyOpenSSL | 0 | 23.2.0-150400.3.13.1 |
| SUSE:Linux Enterprise Server for SAP Applications 15 SP5 | python-pyOpenSSL | 0 | 23.2.0-150400.3.13.1 |
| SUSE:Linux Enterprise Server for SAP Applications 15 SP6 | python-pyOpenSSL | 0 | 23.2.0-150400.3.13.1 |
| Wolfi | airflow-3 | 0 | 3.1.8-r8 |
| Wolfi | az | 0 | 2.84.0-r3 |
| Wolfi | py3-cassandra-medusa | 0 | 0.27.0-r5 |
| Wolfi | superset-5.0 | 0 | 5.0.0-r20 |
| Wolfi | superset-6.0 | 0 | 6.0.0-r4 |
| openSUSE:Leap 15.6 | python-pyOpenSSL | 0 | 23.2.0-150400.3.13.1 |
| openSUSE:Leap 16.0 | python-pyOpenSSL | 0 | 25.0.0-160000.3.1 |
| openSUSE:Tumbleweed | python-pyOpenSSL | 0 | 26.0.0-1.1 |
Related vulnerabilities
- CVE-2026-4539 A security flaw has been discovered in pygments up to 2.19.2. Also affects airflow-2
- CVE-2026-30922 pyasn1 is a generic ASN.1 library for Python. Also affects airflow-2
- CVE-2026-27459 pyOpenSSL is a Python wrapper around the OpenSSL library. Also affects airflow-2
- CVE-2026-32597 PyJWT is a JSON Web Token implementation in Python. Also affects airflow-2
- CVE-2026-31958 Tornado is a Python web framework and asynchronous networking library. Also affects airflow-2
- CVE-2026-25604 In AWS Auth manager, the origin of the SAML authentication has been used as provided by… Also affects airflow-2
- CVE-2025-69219 A user with access to the DB could craft a database entry that would result in executing… Also affects airflow-2
- CVE-2026-27199 Werkzeug is a comprehensive WSGI web application library. Also affects airflow-2