apache / apache/pulsar

PIP-478: SAN-only hostname verification does not hold on a Conscrypt-pinned deployment while SecurityUtility is loaded

Open
#26,278 0 comments 0 reactions 1 assignee Claimed by @lhotari View on GitHub
type/enhancement
Dominant language
Java
Stars
15.3k
Forks
3.8k
Avg merge
1d 14h
Merged PRs (30d)
160

Description

**PIP:** [PIP-478](https://github.com/apache/pulsar/pull/25890) · **Tracking constraint for the TLS migration PRs**

### Background

PIP-478 removes the deprecated CN-based hostname matching in Pulsar 5.0: certificates must carry the
hostname in the SubjectAltName extension, and hostname verification is delegated to the JDK/provider
standard endpoint identification (RFC 2818, SAN-based).

The new `JcaProviders` (added in #26271) deliberately installs **no** custom hostname verifier, so
Conscrypt keeps its built-in default — standard SAN-based verification. Its
`processConscryptTrustManagers` then propagates Conscrypt's *default* verifier onto each
`TrustManager`, working around [conscrypt#1015](https://github.com/google/conscrypt/issues/1015),
where a Conscrypt `TrustManagerImpl` obtained through the standard JSSE `TrustManagerFactory` does not
otherwise pick the default verifier up.

### The problem

`Conscrypt.setDefaultHostnameVerifier` is **process-global**, and the still-wired PIP-337 path sets it
to the CN-tolerant verifier: `SecurityUtility`'s static initializer installs
`TlsHostnameVerifier`, which by design continues to accept a hostname in the certificate's CN.

So whenever `SecurityUtility` has been class-loaded anywhere in the JVM — which it is, for as long as
the PIP-337 stack remains the wired implementation — the "default" propagated onto the new stack's
trust managers is that **relaxed** verifier, not Conscrypt's own. On a Conscrypt-pinned deployment the
SAN-only guarantee then silently does not hold: a certificate carrying the hostname only in the CN
would be accepted where the design says it must be rejected.

### Impact today

**None.** Nothing routes through the new TLS stack yet — #26271 is additive and the PIP-337 path is
still the implementation in use. This is a constraint on a PR that has not been written, which is why
it is tracked here rather than only as a code comment (the comment lives in `JcaProviders`, in a file
the constrained PR may never touch).

### What needs to happen

The PR that turns SAN-only hostname verification on by default, and wires the new TLS stack, must
either:

- neutralize `SecurityUtility`'s global `Conscrypt.setDefaultHostnameVerifier` call before or
atomically with wiring the new path, or
- land together with `SecurityUtility`'s removal (the final PR of the PIP-478 series), so the global
is gone by the time anything depends on the SAN-only behaviour.

Verifying it needs a Conscrypt-pinned deployment presenting a CN-only certificate, asserting the
handshake is rejected.

### Origin

Raised in review of #26271 (https://github.com/apache/pulsar/pull/26271#discussion_r3716896671).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.