Skip to content

Return a minimal response for inactive tokens in /introspect - #4066

Draft
duanemay wants to merge 1 commit into
developfrom
fix/introspect-inactive-token-revocable-leak
Draft

Return a minimal response for inactive tokens in /introspect#4066
duanemay wants to merge 1 commit into
developfrom
fix/introspect-inactive-token-revocable-leak

Conversation

@duanemay

@duanemay duanemay commented Sep 4, 2026

Copy link
Copy Markdown
Member

Summary

  • RFC 7662 section 2.2 requires an inactive-token introspection response to contain only "active": false and nothing else — the authorization server SHOULD NOT include any additional information about an inactive token.
  • IntrospectEndpoint was returning an empty IntrospectionClaims instance for expired/invalid tokens, relying on @JsonInclude(NON_NULL) to hide unset fields. That doesn't work for revocable, which is a primitive boolean inherited from Claims — primitives can't be null, so Jackson always serializes their default value. The response leaked "revocable":false alongside "active":false.
  • IntrospectEndpoint#introspect now returns a plain minimal value ({"active": false}) for the inactive cases, and the populated IntrospectionClaims object only for the active case. This was chosen over suppressing revocable via @JsonInclude because that would also hide a legitimately-false revocable value on an active token's response, which is real information that should still be returned.

Test plan

  • IntrospectEndpointTest#expiredTokenIsInactive / invalidToken_inReadAccessToken / invalidToken_inLoadAuthentication / invalidJSONInClaims — updated to assert the inactive response is exactly {"active": false}.
  • IntrospectEndpointTest#falseRevocableClaimIsNotSuppressedOnActiveToken — new test confirming an active token with an explicit "revocable":false claim still returns it.
  • IntrospectEndpointMockMvcTest#invalidTokenResponseContainsOnlyActiveField — new HTTP-level test asserting the raw response body for an invalid token is exactly {"active":false}.
  • Existing IntrospectEndpointTest, IntrospectEndpointMockMvcTest, and CheckTokenEndpointTests suites pass unchanged.

RFC 7662 section 2.2 requires an inactive-token response to contain
only "active": false and nothing else. IntrospectEndpoint was reusing
an empty IntrospectionClaims instance for this case, but IntrospectionClaims
inherits a primitive `revocable` field from Claims that @JsonInclude(NON_NULL)
cannot suppress, so the response leaked "revocable":false alongside "active":false.
Return a plain minimal value for the inactive case instead, while leaving the
active-token response unchanged (so a legitimately false `revocable` claim on
an active token still appears, as it should).
Copilot AI lite review requested due to automatic review settings September 4, 2026 15:35
@duanemay
duanemay marked this pull request as draft September 4, 2026 15:36

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 change is narrowly scoped, aligns with RFC 7662 requirements, and is covered by updated unit tests plus a new HTTP-level regression test.

Pull request overview

This PR updates UAA’s /introspect endpoint to comply with RFC 7662 §2.2 by returning a truly minimal response for inactive tokens ({"active": false}), avoiding leakage of additional fields (e.g., revocable:false) that can be unintentionally serialized due to primitive defaults.

Changes:

  • Changed IntrospectEndpoint#introspect to return a minimal inactive-token payload (Map.of("active", false)) for expired/invalid tokens, and full IntrospectionClaims only for active tokens.
  • Updated and added tests to assert the inactive response contains only the active field, including a new HTTP-level MockMvc assertion.
  • Added a regression test ensuring an active token’s explicit "revocable": false claim is still returned (not suppressed).
File summaries
File Description
server/src/main/java/org/cloudfoundry/identity/uaa/oauth/IntrospectEndpoint.java Returns a minimal inactive-token response and preserves full claims for active tokens.
server/src/test/java/org/cloudfoundry/identity/uaa/oauth/IntrospectEndpointTest.java Adjusts unit tests for the new inactive payload and adds a regression test for revocable:false on active tokens.
uaa/src/test/java/org/cloudfoundry/identity/uaa/oauth/IntrospectEndpointMockMvcTest.java Adds an HTTP-level test asserting the inactive response body contains only active:false.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 2
  • Review effort level: Lite

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

Comment on lines +26 to +29
// RFC 7662 section 2.2: an inactive-token response MUST contain only "active": false
// and SHOULD NOT include any other information about the token. IntrospectionClaims
// has other fields (e.g. `revocable`, a primitive) that can't be suppressed via
// @JsonInclude once populated, so the inactive case returns this minimal value instead.
Comment on lines +90 to +92
.andExpect(status().isOk())
.andExpect(content().string("{\"active\":false}"));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

2 participants