Skip to content

fix(provider): enforce X.509-SVID leaf profile validation#433

Open
maxlambrecht wants to merge 1 commit into
spiffe:mainfrom
maxlambrecht:fix/trust-manager-x509-svid-profile
Open

fix(provider): enforce X.509-SVID leaf profile validation#433
maxlambrecht wants to merge 1 commit into
spiffe:mainfrom
maxlambrecht:fix/trust-manager-x509-svid-profile

Conversation

@maxlambrecht

Copy link
Copy Markdown
Member

What

Enforce X.509-SVID leaf profile validation when SpiffeTrustManager validates TLS peer certificate chains.

This extracts the existing X509Svid leaf checks into a package-private X509SvidProfile helper and reuses it from both X509Svid parsing and X509SvidValidator.verifyChain(...).

Why

SpiffeTrustManager previously extracted and authorized the SPIFFE ID and performed PKIX validation, but it did not reject peer leaf certificates that violated the X.509-SVID leaf profile.

This closes that gap by rejecting peer leaf certificates with CA=true, missing digitalSignature, keyCertSign, cRLSign, or more than one URI SAN, including one SPIFFE URI plus an additional non-SPIFFE URI.

How tested

Ran:

./gradlew :java-spiffe-core:test --tests io.spiffe.svid.x509svid.X509SvidTest --tests io.spiffe.svid.x509svid.X509SvidValidatorTest :java-spiffe-provider:test --tests io.spiffe.provider.SpiffeTrustManagerTest

@maxlambrecht
maxlambrecht requested a review from rturner3 as a code owner May 9, 2026 20:15
@maxlambrecht
maxlambrecht force-pushed the fix/trust-manager-x509-svid-profile branch 2 times, most recently from 2ada65e to 5c5b85b Compare May 9, 2026 20:37
@maxlambrecht
maxlambrecht force-pushed the fix/trust-manager-x509-svid-profile branch from 5c5b85b to c4cb49b Compare July 18, 2026 20:37
bcleenders added a commit to bcleenders/java-spiffe that referenced this pull request Jul 22, 2026
`SpiffeTrustManager` invoked the `SpiffeIdVerifier` before any
cryptographic validation.
The callback received an unvalidated, attacker-supplied chain despite the verifier's [API spec calling it `verifiedChain`](https://github.com/spiffe/java-spiffe/blob/55200fc8e6b01f9da5951c379e4f4187d7f920b7/java-spiffe-provider/src/main/java/io/spiffe/provider/SpiffeIdVerifier.java#L13).

Validate the chain against the trust bundle first and only then invoke the verifier.

This matches go-spiffe, where [the `Authorizer` only receives chains returned by `x509svid.ParseAndVerify`](https://github.com/spiffe/go-spiffe/blob/v2.8.1/spiffetls/tlsconfig/config.go#L193-L201) (ParseAndVerify first checks the certificates, authorizer checks if the SPIFFE ID is authorized).

Observable change: for a chain that is both untrusted and carries an unacceptable SPIFFE ID, the reported error is now the chain validation failure, rather than the verifier error.

There is a small conflict on imports with spiffe#433 , so if you poke me after that one is merged, I'm happy to rebase.
bcleenders added a commit to bcleenders/java-spiffe that referenced this pull request Jul 22, 2026
`SpiffeTrustManager` invoked the `SpiffeIdVerifier` before any
cryptographic validation.
The callback received an unvalidated, attacker-supplied chain despite the verifier's [API spec calling it `verifiedChain`](https://github.com/spiffe/java-spiffe/blob/55200fc8e6b01f9da5951c379e4f4187d7f920b7/java-spiffe-provider/src/main/java/io/spiffe/provider/SpiffeIdVerifier.java#L13).

Validate the chain against the trust bundle first and only then invoke the verifier.

This matches go-spiffe, where [the `Authorizer` only receives chains returned by `x509svid.ParseAndVerify`](https://github.com/spiffe/go-spiffe/blob/v2.8.1/spiffetls/tlsconfig/config.go#L193-L201) (`ParseAndVerify` first checks the certificates, afterwards `Authorizer` checks if the SPIFFE ID is authorized).

Observable change: for a chain that is both untrusted and carries an unacceptable SPIFFE ID, the reported error is now the chain validation failure, rather than the verifier error.

There is a small conflict on imports with spiffe#433 , so if you poke me after that one is merged, I'm happy to rebase.
bcleenders added a commit to bcleenders/java-spiffe that referenced this pull request Jul 22, 2026
`SpiffeTrustManager` invoked the `SpiffeIdVerifier` before any
cryptographic validation.
The callback received an unvalidated, attacker-supplied chain despite the verifier's [API spec calling it `verifiedChain`](https://github.com/spiffe/java-spiffe/blob/55200fc8e6b01f9da5951c379e4f4187d7f920b7/java-spiffe-provider/src/main/java/io/spiffe/provider/SpiffeIdVerifier.java#L13).

Validate the chain against the trust bundle first and only then invoke the verifier.

This matches go-spiffe, where [the `Authorizer` only receives chains returned by `x509svid.ParseAndVerify`](https://github.com/spiffe/go-spiffe/blob/v2.8.1/spiffetls/tlsconfig/config.go#L193-L201) (`ParseAndVerify` first checks the certificates, afterwards `Authorizer` checks if the SPIFFE ID is authorized).

Observable change: for a chain that is both untrusted and carries an unacceptable SPIFFE ID, the reported error is now the chain validation failure, rather than the verifier error.

There is a small conflict on imports with spiffe#433 , so if you poke me after that one is merged, I'm happy to rebase.

Signed-off-by: bcleenders <[email protected]>
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.

1 participant