Skip to content

Handle Cronet by re-enabling pinning bypass for local trust anchors - #234

Merged
pimterry merged 1 commit into
httptoolkit:mainfrom
az-xx:cronet-pinning-bypass
Sep 18, 2026
Merged

pimterry merged 1 commit into
httptoolkit:mainfrom
az-xx:cronet-pinning-bypass

Conversation

@az-xx

@az-xx az-xx commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

What this adds

Cronet — Chromium's network stack, used by many Google apps, gRPC and various other SDKs — runs TLS itself in native code and ignores the JVM proxy, OkHttp and TrustManager layers entirely, so none of the existing hooks in android-certificate-unpinning.js affect it.

Cronet does trust locally-installed CAs by default, but only while public-key-pinning bypass for local trust anchors is left enabled. An app can turn that off with a single builder call:

new CronetEngine.Builder(context)
    .enablePublicKeyPinningBypassForLocalTrustAnchors(false)
    // ...

…after which even a user/admin-installed CA (like the one this toolkit injects) can no longer intercept its connections.

The fix

Hook org.chromium.net.CronetEngine$Builder.enablePublicKeyPinningBypassForLocalTrustAnchors to always pass true, regardless of what the app requested, and return the builder so chaining keeps working.

This follows the same philosophy as the surrounding hooks — it disables only the extra restriction (pinning layered on top of a locally-trusted CA), so the injected CA is accepted while pinning stays fully intact for connections that chain to a real, non-local trust anchor. addPublicKeyPins is deliberately left untouched for that reason.

Notes

  • The class is skipped automatically on apps that don't bundle Cronet, exactly like every other entry in PINNING_FIXES.
  • The hooked signature is part of the public org.chromium.net API (CronetEngine.Builder).

@CLAassistant

CLAassistant commented Sep 18, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Comment thread android/android-certificate-unpinning.js Outdated
Cronet (Chromium's network stack, used by many Google apps, gRPC and
other SDKs) runs TLS in native code and ignores the JVM proxy, OkHttp
and TrustManager layers, so none of the existing unpinning hooks affect
it. It trusts locally-installed CAs by default, but only while
public-key-pinning bypass for local trust anchors is left enabled, which
an app can turn off with a single CronetEngine.Builder call.

Hook enablePublicKeyPinningBypassForLocalTrustAnchors to always pass
true, so our injected CA is accepted while pinning stays intact for
connections chaining to a real (non-local) trust anchor - matching the
"disable only the extra restrictions" approach the other hooks take.
@az-xx
az-xx force-pushed the cronet-pinning-bypass branch from 0b8cf35 to 939a596 Compare September 18, 2026 11:45
@pimterry

Copy link
Copy Markdown
Member

That's perfect, thanks @az-xx! Merged.

@pimterry
pimterry merged commit b3ea8f6 into httptoolkit:main Sep 18, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants