Open vsfeedback opened 1 month ago
If you add the following to your Program.cs, does that fix your issue?
builder.Services.AddAntiforgery(options =>
{
options.Cookie.SameSite = SameSiteMode.None;
});
It appears that when the browser navigates to the /weather
endpoint from another domain, antiforgery tries to reset the cookie because it wasn't sent during the initial request to the /weather
endpoint. This invalidates the anti-csrf token used previously to render the /test
form which was based on the previous cookie that got reset.
I don't think using SameSiteMode.None
for the antiforgery cookie is a problem because an attacker trying to execute a cross-site request forgery attack should still be unable to generate a valid anti-csrf token. Maybe we should change the default.
However, I also see no reason Blazor should be triggering antiforgery logic at all when hitting the /weather
endpoint. Not only is it inefficient, but it can also lead to problems like this. I know we're concerned about a form being rendered at a later point interactively, but maybe we could lazily make a delayed fetch request to get a valid cookie only once a form is rendered for components that support interactivity.
@blowdart @GrabYourPitchforks @javiercn Do any of you have opinions about using SameSiteMode.None
for the antiforgery cookie? What about making that the default?
However, I also see no reason Blazor should be triggering antiforgery logic at all when hitting the /weather endpoint. Not only is it inefficient, but it can also lead to problems like this. I know we're concerned about a form being rendered at a later point interactively, but maybe we could lazily make a delayed fetch request to get a valid cookie only once a form is rendered for components that support interactivity.
We have a bug for this, I'd rather fix this behavior than changing the cookie
If you add the following to your Program.cs, does that fix your issue?
builder.Services.AddAntiforgery(options => { options.Cookie.SameSite = SameSiteMode.None; });
Thank you! It works for this use case, but it breaks another: if you open from another domain "/test" page in a new tab, the test page returns a 400 when submitting the form. (Without these edits, this use case works)
,
This issue has been moved from a ticket on Developer Community.
[severity:It bothers me. A fix would be nice] Problem: [Error 400][A valid antiforgery token was not provided with the request. Add an antiforgery token, or disable antiforgery validation for this endpoint] for a static SSR page, related to the constant antiforgery token update, if the redirect was from another domain.
I created a new default project BWA i-auto (i(nteractive)-server & i-wasm) + "include sample pages" in the latest VS 17.11.4 . I am attaching the project BlazorApp2.7z, it is a default + one simple test page (/test) with an edit form only.
If you open the /test page in a new tab and click submit - then the page works; Then if you open another /weather (sr-s-SSR=streaming rendering static SSR) page in a new tab from another domain - the previous page immediately gives 400 when submitting the form. (demonstrated in the video bandicam 2024-10-06 13-32-03-490.mp4) The problem is that the antiforgery token is updated if the redirect was to a new tab from another domain (demonstrated in the video bandicam 2024-10-06 13-48-18-096.mp4). The server IIS logs contain a new AF-token only for the last POST request to which the server responded with a 400 error. If you repeat this situation with opening the /weather page in a new tab with manual input of the url - then there is no such problem.
Is this a bug or some kind of Blazor technology issue for static pages? Can MS solve it?
The sample is temporarily deployed blazorapp220241005182634.azurewebsites.net
Possible workaround 1 for a s-SSR page: So far I see this workround: Use a js function that will check that the AF-token has not changed after loading the page and pressing the submit button. If it has changed, refresh the page (the AF-token will be updated automatically) or first ask the user to confirm that the page should be refreshed. But af-token cannot be read from cookies by design as "Httponly cookies' purpose is being inaccessible by script."
The question: How to find out with JavaScript that the AF-token has changed (a boolean sign is enough)?
Possible workaround 2 for a s-SSR page: When pages (like /weather) load, they detect that the token has changed and write the current timestamp to the browser's local storage. The test page, when a button is pressed, will detect that the state has changed (compare the timestamps via JS).
The question: How to find out with C# (OnInitializedAsync) that the AF-token has changed (a boolean sign is enough)?
Original Comments
Feedback Bot on 10/7/2024, 08:21 PM:
We have directed your feedback to the appropriate engineering team for further evaluation. The team will review the feedback and notify you about the next steps.