Skip to content

Apply consistent redirect-URI validation on AccountController.SignIn#3940

Merged
iNinja merged 2 commits into
masterfrom
iinglese/fix-signin-redirect-validation
Jul 13, 2026
Merged

Apply consistent redirect-URI validation on AccountController.SignIn#3940
iNinja merged 2 commits into
masterfrom
iinglese/fix-signin-redirect-validation

Conversation

@iNinja

@iNinja iNinja commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

AccountController.SignIn validated the redirectUri query parameter with Url.IsLocalUrl(redirectUri) only. The sibling Challenge action already had an additional guard -- !IsPercentEncodedSlashBypass(redirectUri) -- that was added in a previous PR but was not applied to SignIn.

A redirectUri value of /%2fevil.example passes Url.IsLocalUrl because the framework checks only for literal // and /\ prefixes. A normalising reverse proxy that decodes percent-encoded path segments can turn that into //evil.example on the way out, which browsers treat as a protocol-relative URL.

Changes

  • AccountController.cs: add && !IsPercentEncodedSlashBypass(redirectUri) to the SignIn redirect guard, matching the check on Challenge.
  • AccountController.cs: expand the IsPercentEncodedSlashBypass XML doc to note it is a local copy of RedirectUriHelper.HasPercentEncodedSlashPrefix (which is internal in a separate assembly) so future changes keep both in sync.
  • AccountControllerTests.cs: two new tests covering the %2f and %5c variants on the SignIn path, using the realistic IsLocalUrl mock already present in the test class.

SignIn was missing the IsPercentEncodedSlashBypass guard that Challenge
already had. A redirectUri like /%2fevil.example passes Url.IsLocalUrl
(the framework only checks for literal // and /\), but a normalising
reverse proxy decodes it to //evil.example; browsers then follow it as
a protocol-relative URL after sign-in.

Add !IsPercentEncodedSlashBypass(redirectUri) to the SignIn guard,
matching the guard on Challenge.

Also update the IsPercentEncodedSlashBypass XML doc to note it is a
local copy of RedirectUriHelper.HasPercentEncodedSlashPrefix (internal
in a separate assembly) so future changes keep both in sync.

Tests: two new facts in AccountControllerTests covering the %2f and %5c
variants on the SignIn path, using the realistic IsLocalUrl mock so
removing either guard breaks the tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 00c4f24d-188f-4bd9-926c-a6d0620eb053
@iNinja
iNinja requested a review from a team as a code owner July 13, 2026 13:12
@iNinja
iNinja merged commit 45efdba into master Jul 13, 2026
8 checks passed
@iNinja
iNinja deleted the iinglese/fix-signin-redirect-validation branch July 13, 2026 15:11
This was referenced Jul 17, 2026
This was referenced Jul 19, 2026
github-actions Bot pushed a commit to EelcoLos/nx-tinkering that referenced this pull request Jul 21, 2026
Pinned
[Microsoft.Identity.Web](https://github.com/AzureAD/microsoft-identity-web)
at 4.13.2.

<details>
<summary>Release notes</summary>

_Sourced from [Microsoft.Identity.Web's
releases](https://github.com/AzureAD/microsoft-identity-web/releases)._

## 4.13.2

## What's Changed
* Apply reserved-header handling on the request-clone path and cover all
X-MS-TOKEN- headers by @​iNinja in
AzureAD/microsoft-identity-web#3915
* Restore independent PR pipeline + pool-aware MI identity + net462/472
unit tests by @​iarekk in
AzureAD/microsoft-identity-web#3935
* Post-release 4.13.0: changelog and public API shipped move by
@​neha-bhargava in
AzureAD/microsoft-identity-web#3937
* Remove redundant 'Run unit tests' GitHub Action by @​iarekk in
AzureAD/microsoft-identity-web#3939
* Apply consistent redirect-URI validation on AccountController.SignIn
by @​iNinja in
AzureAD/microsoft-identity-web#3940
* Fix duplicate logging of MsalUiRequiredException (in-repo copy of
#​3910) by @​iarekk in
AzureAD/microsoft-identity-web#3941
* Use MSAL's recent UserFIC API for agentic flows by @​Avery-Dunn in
AzureAD/microsoft-identity-web#3842
* Restore CustomizeHttpRequestMessage to run after the authorization
header by @​neha-bhargava in
AzureAD/microsoft-identity-web#3943
* Bump Microsoft.IdentityModel.Tokens.Saml from 5.7.0 to 8.19.1 by
@​dependabot[bot] in
AzureAD/microsoft-identity-web#3909
* Revert #​3909: keep OWIN Saml/WsFederation on 5.7.0 by @​iarekk in
AzureAD/microsoft-identity-web#3944
* Bump Microsoft.Identity.Abstractions from 12.4.0 to 12.5.0 by
@​neha-bhargava in
AzureAD/microsoft-identity-web#3947
* Add OnBeforeAuthHeaderCreation / OnAfterAuthHeaderCreation hooks to
DownstreamApi by @​neha-bhargava in
AzureAD/microsoft-identity-web#3942
* Update IdentityModelV5Version and SamlPackageVersion to 5.7.1 in proj…
by @​trwalke in
AzureAD/microsoft-identity-web#3950
* Rename retired MSALMSIV2 agent pool to MISEManagedIdentity by
@​gladjohn with @​Copilot in
AzureAD/microsoft-identity-web#3949
* Improve IDW10109 error handling for credential loading failures by
@​Avery-Dunn in
AzureAD/microsoft-identity-web#3946
* Bump MSAL dependencies to 4.86.1 in central props by @​gladjohn with
@​Copilot in AzureAD/microsoft-identity-web#3953
* Bump the notsecurity group with 3 updates by @​dependabot[bot] in
AzureAD/microsoft-identity-web#3954


**Full Changelog**:
AzureAD/microsoft-identity-web@4.13.0...4.13.2

Commits viewable in [compare
view](AzureAD/microsoft-identity-web@4.13.0...4.13.2).
</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
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.

3 participants