dotnet / dotnet/aspnetcore

InvalidOperationException: Invalid return url. The return url needs to have the same origin as the current page.

Open
#24,316 8 comments 1 reaction 0 assignees View on GitHub
affected-few area-blazor bug feature-blazor-wasm feature-blazor-wasm-auth Pillar: Technical Debt Priority:1 severity-major
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

I host my blazor webassembly application in sub-directory - https://localhost:5000/myapp

Base path is defined in index.html: ``

I use identity server for authentication so there is link to authentication page from component NotLoggedIn.razor:
`log in`

and authentication page
```
@page "/authentication/{action}"

...

@code{
[Parameter] public string Action { get; set; }
}
```

When I navigate to https://localhost:5000/myapp/ it works as expected.

When I navigate to https://localhost:5000/myapp exception happens:

> Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
> Unhandled exception rendering component: Invalid return url. The return url needs to have the same origin as the current page.
> System.InvalidOperationException: Invalid return url. The return url needs to have the same origin as the current page.
> at Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticatorViewCore`1[TAuthenticationState].GetReturnUrl (TAuthenticationState state, System.String defaultReturnUrl) <0x333cda8 + 0x00098> in :0
> at Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticatorViewCore`1[TAuthenticationState].OnParametersSetAsync () <0x333c238 + 0x001f0> in :0
> at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion (System.Threading.Tasks.Task task) <0x31b2bd8 + 0x000da> in :0
> at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync () <0x2f63bf8 + 0x001d8> in :0
>

This happens in method GetReturnUrl of RemoteAuthenticatorViewCore ln 346

```
private string GetReturnUrl(TAuthenticationState state, string defaultReturnUrl = null)
{
if (state?.ReturnUrl != null)
{
return state.ReturnUrl;
}

var fromQuery = QueryStringHelper.GetParameter(new Uri(Navigation.Uri).Query, "returnUrl");
if (!string.IsNullOrWhiteSpace(fromQuery) && !fromQuery.StartsWith(Navigation.BaseUri))
{
// This is an extra check to prevent open redirects.
throw new InvalidOperationException("Invalid return url. The return url needs to have the same origin as the current page.");
}

return fromQuery ?? defaultReturnUrl ?? Navigation.BaseUri;
}
```

Because base path defined with slash on the end but current path doesn't contains slash the check: `!fromQuery.StartsWith(Navigation.BaseUri)` is true.

Unfortunately I cannot define base w/o slash on the end because it breaks navigation.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.