Skip to content

Restrict the stateless token-API request matcher to the user_token grant - #4056

Merged
duanemay merged 1 commit into
developfrom
fix/client-credentials-bearer-auth-bypass
Aug 27, 2026
Merged

Restrict the stateless token-API request matcher to the user_token grant#4056
duanemay merged 1 commit into
developfrom
fix/client-credentials-bearer-auth-bypass

Conversation

@duanemay

Copy link
Copy Markdown
Member

oauthTokenApiRequestMatcher matched any /oauth/token request bearing an
Authorization: Bearer header and a client_id parameter, regardless of
grant_type. It was written for exactly one purpose (see the historical
XML config comment this replaced): UAA's non-standard user_token grant.

Because it never checked grant_type, a standard grant_type=client_credentials
request carrying a Bearer header and matching client_id also matched it,
routing the request to the uaa.user-scope-only resource filter chain
instead of the client-secret-authenticated one. TokenEndpoint then treated
the Bearer token's own client as "the authenticated client," and the one
remaining safety net (AbstractTokenGranter#isValidClientAuthentication)
fails open to CLIENT_AUTH_SECRET whenever it can't positively identify how
the client was authenticated - which is exactly the case for a
resource-owner Bearer token. Net effect: any user holding a plain access
token for a client that also supports client_credentials could mint a new
token carrying that client's own authorities, with no proof of the
client's secret.

Constraining the matcher to grant_type=user_token, matching its original
documented scope, routes client_credentials requests to the correct
client-secret-authenticated chain again.

oauthTokenApiRequestMatcher matched any /oauth/token request bearing an
Authorization: Bearer header and a client_id parameter, regardless of
grant_type. It was written for exactly one purpose (see the historical
XML config comment this replaced): UAA's non-standard user_token grant.

Because it never checked grant_type, a standard grant_type=client_credentials
request carrying a Bearer header and matching client_id also matched it,
routing the request to the uaa.user-scope-only resource filter chain
instead of the client-secret-authenticated one. TokenEndpoint then treated
the Bearer token's own client as "the authenticated client," and the one
remaining safety net (AbstractTokenGranter#isValidClientAuthentication)
fails open to CLIENT_AUTH_SECRET whenever it can't positively identify how
the client was authenticated - which is exactly the case for a
resource-owner Bearer token. Net effect: any user holding a plain access
token for a client that also supports client_credentials could mint a new
token carrying that client's own authorities, with no proof of the
client's secret.

Constraining the matcher to grant_type=user_token, matching its original
documented scope, routes client_credentials requests to the correct
client-secret-authenticated chain again.
Copilot AI lite review requested due to automatic review settings August 25, 2026 20:29

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.

Pull request overview

This PR fixes a security-relevant filter-chain routing bug in the /oauth/token endpoint by narrowing the “stateless token API” request matcher to only apply to UAA’s non-standard user_token grant, ensuring standard grants (notably client_credentials) are routed through the client-secret-authenticated chain.

Changes:

  • Restrict oauthTokenApiRequestMatcher to require grant_type=user_token (in addition to Bearer auth header + client_id).
  • Add a regression test asserting a user access token cannot be presented as Bearer “client authentication” for client_credentials requests.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/token/TokenMvcMockTests.java Adds a regression test to prevent Bearer user tokens from being accepted as client authentication for client_credentials.
server/src/main/java/org/cloudfoundry/identity/uaa/oauth/beans/OauthEndpointBeanConfiguration.java Tightens the /oauth/token stateless matcher so it only matches grant_type=user_token, restoring correct routing for other grants.

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

@github-project-automation github-project-automation Bot moved this from Inbox to Pending Merge | Prioritized in Foundational Infrastructure Working Group Aug 27, 2026
@strehle
strehle requested a lite review from Copilot August 27, 2026 14:12

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.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@duanemay
duanemay merged commit e89bdca into develop Aug 27, 2026
34 of 35 checks passed
@duanemay
duanemay deleted the fix/client-credentials-bearer-auth-bypass branch August 27, 2026 14:26
@github-project-automation github-project-automation Bot moved this from Pending Merge | Prioritized to Done in Foundational Infrastructure Working Group Aug 27, 2026
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.

4 participants