Skip to content

ssl: distrust compromised eMudhra intermediate CA keys #160040

Closed

Description

@tiran

Feature or enhancement

I propose to add a small denylist to _ssl that rejects any TLS certificate chain containing one of the recently compromised eMudhra intermediate CA keys. The check runs during certificate verification and matches the DER-encoded SubjectPublicKeyInfo, so cross-signed certs that reuse a key are blocked, too.

Yesterday a set of eMudhra intermediate keys were disclosed as compromised and revoked, see https://emudhra.we-have-a-problem.com/. d=4 isn't a secure EC private key. Removing trust is the root store's job, but the update lags in practice, and there is no reliable way to propagate an intermediate revocation to applications. Until the roots are gone, Python still completes handshakes through a known-bad key.

As a defense in depth Python should blocks those connections in the meantime. With a simple callback, this can be enforced on every SSLContext when verification is enabled (CERT_OPTIONAL / CERT_REQUIRED); CERT_NONE is unaffected.

Has this already been discussed elsewhere?

No response given

Links to previous discussion of this feature:

Golang has implemented filtering to address CVE-2026-111943.

Linked PRs

Activity

  1. sethmlarson commented on Oct 21, 2026

    @sethmlarson
    Contributor

    @tiran Thanks, I'm okay moving forward if this is clear to users and distributions why this list exists and that it's not to be relied on for a timely defense to compromised certificates. Does Go publish any of their thinking or documentation around their decision to adopt this?

    I've also confirmed with RMs that there is willingness to backport this PR to prior versions, so it will be more effective than only landing in 3.16.

  2. tomato42 commented on Oct 21, 2026

    @tomato42

    While, yes, this is a sub-optimal solution, the proper solution (have OpenSSL and similar libraries able to consume OneCRL or CRLSets) is still some time away, but it is being worked on.

    Node.js also implemented the blocklist: nodejs/node#66871

  3. zooba commented on Oct 21, 2026

    @zooba
    Member

    Let's document when and why Python is blocking certificates:

    Let's also be clear that it is not a security boundary, and we are not obliged to treat changes to the blocklist or its behaviour as vulnerabilities. No change to the blocklist will be embargoed, and its presence should not cause the PSRT to be included in pre-disclosure analysis or updates of future issues. We'll make updates in public after the problems are disclosed and after actual certificate bundle distributors have updated their bundles/revocation lists.

    It's 2026 and certifi is still a thing

    Yes, I'd really hoped we'd have a more secure (aka less configurable) "access HTTPS endpoint" API by now to take the most burden of what everyone wants certifi for. Something without OpenSSL being part of the public API (which is what prevents us reliably relying on the OS functionality).

  4. added a commit that references this issue on Oct 21, 2026
  5. tiran commented on Oct 22, 2026

    @tiran
    MemberAuthor

    Yes, I'd really hoped we'd have a more secure (aka less configurable) "access HTTPS endpoint" API by now to take the most burden of what everyone wants certifi for. Something without OpenSSL being part of the public API (which is what prevents us reliably relying on the OS functionality).

    Nope :/

    In my scans I even found packages with recent releases that had an ancient CA bundle from about 2015/2016. The bundle had the Comodo AAA cross-sign cert, distrusted StartCom+WoSign, and were lacking the Let's Encrypt ISRG Root X1 CA.

  6. added a commit that references this issue on Oct 22, 2026
  7. Yhg1s commented on Oct 22, 2026

    @Yhg1s
    Member

    FWIW, I think this is a reasonable action to take at this point, and I don't think it creates unreasonable expectations.. We're helping people avoid getting MITM'd because we can, not because we're the right place to do so. (It's also quite attractive that this will let people on the patched versions of Python upgrade to a safe version of pip by simply running python -m pip install -U pip, without having to know about hashes and URLs.)

  8. willingc commented on Oct 22, 2026

    @willingc
    Contributor

    FWIW, I think this is a reasonable action to take at this point, and I don't think it creates unreasonable expectations.. We're helping people avoid getting MITM'd because we can, not because we're the right place to do so.

    I agree with @Yhg1s.

    Thanks core team, RMs, and PSF security folks for getting information out in a timely and helpful way. Anything that we can do to help maintainers who are not security experts (such as scientific Python package maintainers) to get things more secure is very much appreciated.

    P.S. Thanks @tiran for all of your help, and it's great to see you here. I've missed you.

  9. added 3 commits that reference this issue on Oct 22, 2026
  10. tiran commented on Oct 23, 2026

    @tiran
    MemberAuthor

    FYI, following some concern I have removed a test script from my PR and made a more complete verification script available in a personal gist, https://gist.github.com/tiran/8aec252a9f41e33efa0ed31832c8ca8b .

  11. added a commit that references this issue on Oct 23, 2026
  12. added a commit that references this issue on Oct 24, 2026
  13. added a commit that references this issue on Oct 24, 2026
  14. gpshead commented on Oct 24, 2026

    @gpshead
    Member

    While we don't support 3.10 or 3.9 anymore, since I was having Claude produce the backports anyways I had it go ahead and produce, untested by me, 3.10 and 3.9 backports as well:

    Branches:

    Commits:

  15. added 2 commits that reference this issue on Oct 24, 2026
  16. moved this from Todo to In Progress in Release and Deferred blockers 🚫on Oct 24, 2026
  17. tiran commented on Oct 24, 2026

    @tiran
    MemberAuthor

    @sethmlarson @gpshead @Yhg1s @hugovk You may have to release security updates of Python 3.13-3.15 with my fix ASAP.

    Please take a look at @JSGette comment on DataDog/datadog-agent#58679

    Confirmed on the signed 7.84.5 Windows MSI (ZD-3042491, incident_62343): ssl.create_default_context() still accepts the AAA cross-signed eMudhra chains, because Python loads the Windows CA and ROOT stores and never reads Disallowed. On Windows, datadog_checks_base HTTP integrations without tls_ca_cert call load_default_certs() and inherit the same trust.

    It looks like Windows still ships the Sectigo / Comodo AAA Certificate Service in Windows' trust store. ssl.create_default_context() loads the trust anchor. I do not have access to a Windows machine at the moment. Can somebody test and confirm the issue?

  18. hugovk commented on Oct 24, 2026

    @hugovk
    Member

    @tiran I've added you to the bypass list so you can open more PRs.

  19. added 4 commits that reference this issue on Oct 24, 2026
  20. added 5 commits that reference this issue on Oct 24, 2026
  21. moved this from In Progress to Done in Release and Deferred blockers 🚫on Oct 25, 2026
  22. added 7 commits that reference this issue on Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions