Skip to content

Fix OAuth2 authorization loop when grant scope changes#36900

Open
mango766 wants to merge 1 commit intogo-gitea:mainfrom
mango766:fix/oauth2-grant-scope-update
Open

Fix OAuth2 authorization loop when grant scope changes#36900
mango766 wants to merge 1 commit intogo-gitea:mainfrom
mango766:fix/oauth2-grant-scope-update

Conversation

@mango766
Copy link

Summary

  • Fix infinite redirect loop when an OAuth2 client requests a different scope than a user's existing grant
  • Add OAuth2Grant.SetScope() method to update the scope of an existing grant in the database
  • Update GrantApplicationOAuth() to update the grant scope instead of returning a server_error when scopes differ
  • Update AuthorizeOAuth() to sync grant scope for confidential/trusted clients on auto-redirect

Fixes #36762

Details

When an OAuth2 client changes its requested scope (e.g., from repository to read:repository,write:repository,read:user), and a user has a pre-existing grant with the old scope, the GrantApplicationOAuth handler previously returned a server_error to the redirect_uri. Since the OAuth2 client typically retries the authorization flow upon receiving an error, this created an infinite redirect loop with no way for the user to recover through the UI.

This PR updates the grant's scope in the database when the user re-authorizes with a different scope. Since the user has already explicitly consented to the new permissions by clicking "Authorize" on the authorization page, this is safe and expected behavior.

The fix also addresses the related issue for confidential clients and applications with skip_secondary_authorization enabled, where AuthorizeOAuth() auto-redirects using the old grant's scope without updating it.

Test plan

  • Verify that re-authorizing an OAuth2 application with a different scope succeeds without redirect loops
  • Verify that the oauth2_grant table is updated with the new scope
  • Verify that confidential clients receive tokens with the updated scope when the requested scope changes
  • Verify that initial authorization (no existing grant) still works correctly
  • Verify that re-authorization with the same scope still works correctly

When an OAuth2 client requests a different scope than what was
previously granted, the GrantApplicationOAuth handler returned a
server_error to the redirect URI. Since the client typically retries
the authorization, this caused an infinite redirect loop with no way
for the user to recover except by manually deleting the grant from the
database.

Update the existing grant's scope instead of returning an error, since
the user has already explicitly consented to the new scope by clicking
"Authorize" on the authorization page. Also update the scope for
confidential/trusted clients in the AuthorizeOAuth auto-redirect path
so they receive tokens with the correct (current) scope.

Fixes go-gitea#36762

Co-Authored-By: Claude (claude-opus-4-6) <noreply@anthropic.com>
@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Mar 14, 2026
@github-actions github-actions bot added the modifies/go Pull requests that update Go code label Mar 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. modifies/go Pull requests that update Go code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OAuth2 authorization loops when existing grant has different scope

2 participants