Skip to content

[Attestation] Reject attestation tokens whose signature cannot be verified - #50449

Merged
Olga Kroshkina (olkroshk) merged 3 commits into
Azure:mainfrom
olkroshk:dev/olkroshk/2026-09-validate-token
Sep 15, 2026
Merged

Olga Kroshkina (olkroshk) merged 3 commits into
Azure:mainfrom
olkroshk:dev/olkroshk/2026-09-validate-token

Conversation

@olkroshk

@olkroshk Olga Kroshkina (olkroshk) commented Sep 14, 2026

Copy link
Copy Markdown
Member

Description

This pull request fixes a signature verification bypass. In AttestationTokenImpl, validateTokenSignature() returned null for two distinct outcomes — an unsigned token (alg: none) and a signed token that no trusted signer could verify — and validate() accepted both. The null result was only meant to represent "no signature to check," but it was also being returned (and accepted) for "the signature matched no trusted key," so a token signed with an untrusted key passed validation.

This change distinguishes the two cases:

  • An unsigned token still validates (there is no signature to verify).
  • A signed token that no trusted signer can verify is now rejected with an error.

It also removes a fallback where a token with no supplied signers was verified against its own embedded certificate — letting it vouch for itself — which now fails closed.

All SDK Contribution checklist:

  • The pull request does not introduce [breaking changes]
  • CHANGELOG is updated for new features, bug fixes or other significant changes.
  • I have read the contribution guidelines.

General Guidelines and Best Practices

  • Title of the pull request is clear and informative.
  • There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, see this page.

Testing Guidelines

  • Pull request includes test coverage for the included changes.
$env:JAVA_HOME="C:\Program Files\Microsoft\jdk-21.0.12.101-hotspot"; $env:PATH="$env:JAVA_HOME\bin;$env:USERPROFILE\tools\apache-maven-3.9.9\bin;$env:PATH"; mvn -f sdk/attestation/azure-security-attestation/pom.xml "-Dtest=AttestationTokenTests,AttestationTokenValidationTests" -DfailIfNoTests=false test
...
[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.azure.security.attestation.models.AttestationTokenValidationTests
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.649 s -- in com.azure.security.attestation.models.AttestationTokenValidationTests
[INFO] Running com.azure.security.attestation.models.AttestationTokenTests
[INFO] Tests run: 15, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 8.987 s -- in com.azure.security.attestation.models.AttestationTokenTests
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 18, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  23.487 s
[INFO] Finished at: 2026-09-14T16:36:03-07:00
[INFO] ------------------------------------------------------------------------

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
34 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@olkroshk Olga Kroshkina (olkroshk) changed the title Fix attestation JWT signature verification bypass [Attestation] Reject attestation tokens whose signature cannot be verified Sep 14, 2026
@olkroshk
Olga Kroshkina (olkroshk) marked this pull request as ready for review September 14, 2026 23:14
Copilot AI lite review requested due to automatic review settings September 14, 2026 23:14
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
34 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The changes require final human review because they are too complex or risky for automated approval.

Pull request overview

Hardens attestation token validation against signature-verification bypasses.

Changes:

  • Rejects signed tokens that cannot be verified by trusted signers.
  • Removes trust in certificates embedded within tokens when no signers are supplied.
  • Adds offline regression tests and changelog entries.
File summaries
File Description
sdk/attestation/azure-security-attestation/src/test/java/com/azure/security/attestation/models/AttestationTokenValidationTests.java Updated as part of this pull request.
sdk/attestation/azure-security-attestation/src/test/java/com/azure/security/attestation/models/AttestationTokenTests.java Updated as part of this pull request.
sdk/attestation/azure-security-attestation/src/main/java/com/azure/security/attestation/implementation/models/AttestationTokenImpl.java Updated as part of this pull request.
sdk/attestation/azure-security-attestation/CHANGELOG.md Updated as part of this pull request.
Review details

Suppressed comments (1)

sdk/attestation/azure-security-attestation/src/main/java/com/azure/security/attestation/implementation/models/AttestationTokenImpl.java:481

  • This branch no longer follows the helper's Javadoc contract: the documentation above still says that when signers is absent it consults the JWS header for candidate keys, but this code now rejects that case instead of using embedded key material. Please update that Javadoc to state that signed-token validation requires a caller-supplied trusted signer list and never trusts keys embedded in the token.
                // No trusted signers were provided. Do NOT fall back to the key material embedded in the
                // token itself - that would let a token vouch for its own signature and bypass validation
                // (CWE-347). Mirror the other Azure Attestation SDKs and fail closed.
                throw LOGGER.logExceptionAsError(
                    new RuntimeException("Unable to find any certificates which can be used to validate the token."));
  • Files reviewed: 4/4 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The focused security fix fails closed and includes coverage for rejection, trusted acceptance, and missing signers.

Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@olkroshk
Olga Kroshkina (olkroshk) merged commit e47bdcd into Azure:main Sep 15, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants