Skip to content

fix(transport): Reject leaked eMudhra intermediate certificates - #6336

Merged
runningcode merged 6 commits into
mainfrom
no/distrust-emudhra-intermediates
Oct 30, 2026
Merged

runningcode merged 6 commits into
mainfrom
no/distrust-emudhra-intermediates

Conversation

@runningcode

@runningcode runningcode commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

📜 Description

Rejects TLS servers whose certificate was issued by one of the eight leaked eMudhra intermediates (CVE-2026-111943) in the two places where the SDK opens its own HTTPS connections: the envelope transport (HttpConnection) and the distribution update check (DistributionHttpClient).

How does it work:
Both wrap the connection's SSLSocketFactory (the one from SentryOptions.sslSocketFactory, or else the connection's own) with DistrustedCertificates.wrap. The sockets it creates check the server's certificates after every handshake and before the first read or write, then close the socket and throw SSLPeerUnverifiedException if one of them was issued by, or is, a leaked CA. Since that is an IOException, a blocked envelope is kept in the offline cache and retried later.

Why the socket and not once after connect():

  • HttpURLConnection silently opens a new connection to retry a POST when the first one fails before a response, and that handshake was never checked.
  • Android caches intermediates from validated chains and completes a chain the server sent without them, so a server can leave out the leaked CA. The check therefore matches the leaf's issuer by name. None of these CAs may issue further CAs (pathlen:0), so anything they issued is a leaf, and the server always sends the leaf. The name also matches the AAA Certificate Services cross-signs, which share the subject.

On Android 5.0 and 5.1, Conscrypt only sends SNI once setHostname is called, which Android's HTTP stack does by reflection and which does nothing on a wrapper, so the factory makes that call on the real socket. Later versions send SNI by default.

💡 Motivation and Context

https://emudhra.we-have-a-problem.com/

Fixes JAVA-783

💚 How did you test it?

DistrustedCertificatesTest sends envelopes through a real HttpConnection to a MockWebServer over TLS. As in OkHttp's CompromisedIntermediateTest, it signs leaves with the real EM OV TLS CA - G3C certificate, whose private key is 4. It covers the full leaked chain, a leaf-only chain the client completes itself, and a retry on a new connection. The last two pass the old check after connect(). The Android-only SNI path is not tested on a device.

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec.

🔮 Next steps

  • ApacheHttpClientTransport from sentry-apache-http-client-5 doesn't use HttpsURLConnection, so it needs its own check in a follow-up PR.
  • Out of scope: SpotlightIntegration only talks to a local server, and the HTTP client integrations (sentry-okhttp, OpenFeign, Ktor, Spring) instrument the app's own clients, which the app has to fix itself.

🤖 Generated with Claude Code

@linear-code

linear-code Bot commented Oct 21, 2026

Copy link
Copy Markdown

JAVA-783

@github-actions

Copy link
Copy Markdown
Contributor

🚨 Detected changes in high risk code 🚨

High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:

  • sentry/src/main/java/io/sentry/transport/HttpConnection.java

1 similar comment
@github-actions

Copy link
Copy Markdown
Contributor

🚨 Detected changes in high risk code 🚨

High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:

  • sentry/src/main/java/io/sentry/transport/HttpConnection.java

@sentry

sentry Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.62.0 (1) release

⚙️ sentry-android Build Distribution Settings

@runningcode
runningcode force-pushed the no/distrust-emudhra-intermediates branch from 9099fca to c17d99a Compare October 21, 2026 08:56
@github-actions

Copy link
Copy Markdown
Contributor

🚨 Detected changes in high risk code 🚨

High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:

  • sentry/src/main/java/io/sentry/transport/HttpConnection.java

@runningcode
runningcode force-pushed the no/distrust-emudhra-intermediates branch from c17d99a to fdafbb8 Compare October 22, 2026 16:08
@github-actions

Copy link
Copy Markdown
Contributor

🚨 Detected changes in high risk code 🚨

High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:

  • sentry/src/main/java/io/sentry/transport/HttpConnection.java

Comment thread sentry/src/main/java/io/sentry/transport/HttpConnection.java Outdated
@runningcode
runningcode marked this pull request as ready for review October 26, 2026 16:57
@runningcode
runningcode force-pushed the no/distrust-emudhra-intermediates branch from fdafbb8 to 099ea84 Compare October 26, 2026 17:02
@github-actions

Copy link
Copy Markdown
Contributor

🚨 Detected changes in high risk code 🚨

High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:

  • sentry/src/main/java/io/sentry/transport/HttpConnection.java

@runningcode runningcode added ship-it PR is ready to merge from a reviewer perspective sanity-check PR needs a lightweight review for obvious issues and removed ship-it PR is ready to merge from a reviewer perspective labels Oct 26, 2026
@runningcode
runningcode requested a review from a team as a code owner October 28, 2026 14:22
@runningcode
runningcode force-pushed the no/distrust-emudhra-intermediates branch from d7b91f1 to cdae9a0 Compare October 28, 2026 15:12
@github-actions

Copy link
Copy Markdown
Contributor

🚨 Detected changes in high risk code 🚨

High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:

  • sentry/src/main/java/io/sentry/transport/HttpConnection.java

1 similar comment
@github-actions

Copy link
Copy Markdown
Contributor

🚨 Detected changes in high risk code 🚨

High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:

  • sentry/src/main/java/io/sentry/transport/HttpConnection.java

Comment thread gradle/libs.versions.toml

@adinauer adinauer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, changelog needs to be moved

runningcode and others added 4 commits October 30, 2026 10:05
The private keys of eight eMudhra intermediates can be recovered from their certificates (CVE-2026-111943). Their Sectigo cross-signs chain to AAA Certificate Services, which is trusted on every Android version, so platform trust store updates won't reach every device. The envelope transport and the distribution client now reject servers that present one of these keys, right after the TLS handshake and before any request is written.

Fixes JAVA-783

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Inject the check through HttpConnection's constructor like AuthenticatorWrapper, so its tests can stub it instead of loading the real eMudhra certificate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Checking the server certificates once after connect() missed the new connections HttpURLConnection opens on its own to retry a request, and chains Android completes from intermediates cached on earlier connections. Wrap the SSLSocketFactory so every handshake is checked, and match the leaf's issuer by name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@runningcode
runningcode force-pushed the no/distrust-emudhra-intermediates branch from 9d8d58a to dc4cea1 Compare October 30, 2026 09:06
@github-actions

Copy link
Copy Markdown
Contributor

🚨 Detected changes in high risk code 🚨

High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:

  • sentry/src/main/java/io/sentry/transport/HttpConnection.java

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

🚨 Detected changes in high risk code 🚨

High-risk code has higher potential to break the SDK and may be hard to test. To prevent severe bugs, apply the rollout process for releasing such changes and be extra careful when changing and reviewing these files:

  • sentry/src/main/java/io/sentry/transport/HttpConnection.java

@runningcode
runningcode enabled auto-merge (squash) October 30, 2026 09:16
@runningcode
runningcode merged commit 6fe2c2e into main Oct 30, 2026
44 checks passed
@runningcode
runningcode deleted the no/distrust-emudhra-intermediates branch October 30, 2026 09:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

sanity-check PR needs a lightweight review for obvious issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants