Skip to content

[release/1.x] Validate OAuth authorization state - #1948

Closed
halter73 wants to merge 2 commits into
release/1.xfrom
halter73-backport-oauth-state-validation
Closed

halter73 wants to merge 2 commits into
release/1.xfrom
halter73-backport-oauth-state-validation

Conversation

@halter73

@halter73 halter73 commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Backport #1726 (merge commit 9c635ff) to release/1.x, keeping its OAuth state behavior aligned with main.

  • Generate a fresh 256-bit, base64url-encoded state for every OAuth authorization-code transaction, including legacy callbacks.
  • Reserve state in AdditionalAuthorizationParameters for all callback paths; attempts to override it are rejected, as in Validate OAuth authorization state #1726.
  • Require an exact response-state match before token exchange for AuthorizationCallbackHandler and the built-in handler. The legacy code-only delegate retains the same validation limitation as main.
  • Update the built-in console handler to parse the full redirect URL, and migrate the protected-client sample and conformance client to return response state.
  • Cover state format, uniqueness, matching, missing/empty/mismatched state, token-exchange blocking, invalid callback results, ambiguous callback configuration, and reserved-parameter rejection for legacy, response-aware, and default callbacks.

Required 1.x adaptations

release/1.x does not have the AuthorizationCallbackHandler, AuthorizationCallbackContext, or AuthorizationResult APIs introduced by #1605, which #1726 depends on. This backport includes the callback plumbing needed to return Code and State; it does not bring over RFC 9207 issuer validation or unrelated #1605 changes. These prerequisites prevent applying #1726 alone as a literal clean cherry-pick, but the state generation, reservation, and validation behavior follows the original change.

The existing 1.x AuthorizationRedirectDelegate is not newly marked obsolete, avoiding an unrelated warning-as-error source break. As on main, it remains functional but returns only a code, so SDK response-state validation is skipped. There is no special exception for caller-supplied state.

The built-in console flow now requires the full redirect URL, not just an authorization code, matching #1726. Code-only callbacks remain supported, but applications using AdditionalAuthorizationParameters["state"] must remove that override, just as on main.

Validation

  • Revised solution: dotnet build --no-restore --nologo --verbosity quiet passed with zero warnings/errors.
  • Revised complete ASP.NET Core suite, including OAuth and conformance tests: 359 passed, 16 skipped on each of .NET 8/9/10.
  • Before this final source-alignment revision, the non-manual solution suite also passed across .NET 8/9/10 and .NET Framework 4.7.2 after installing the pinned npm dependencies and supplying an explicit test-only current-directory PATH entry for process tests.

halter73 and others added 2 commits October 21, 2026 18:18
Adapt #1726 (9c635ff) for release/1.x with additive response callback APIs, preserving legacy code-only delegates and application-managed state.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Remove the legacy caller-managed state exception. Reserve SDK-generated state for every callback path, as in #1726, and cover rejection for legacy, response-aware, and default callbacks.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@halter73

Copy link
Copy Markdown
Contributor Author

Closing in favor of #1949, which backports #1700 and requires advertised S256 PKCE support by default without introducing the newer callback API into 1.x.

RFC 9700 section 4.7.1 permits relying on PKCE for CSRF protection when authorization-server support has been established. The replacement also rejects the unverified no-metadata fallback by default, with an explicit AppContext escape hatch for trusted legacy deployments whose PKCE support is independently known. This is a narrower servicing approach for existing 1.x callbacks; state validation remains additional protection in 2.x. No changes are being made to main.

@halter73 halter73 closed this Oct 22, 2026
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