Problem with multiple MVC tabs ValidateAntiForgeryToken

We received "The required anti-counterfeit token was not delivered or was invalid." errors and in the course of some further research, I was able to recreate the problem in its simplest form - I either do something completely wrong, or this is a limitation of the anti-fake token system.

Anyway, I would appreciate some advice!

Empty MVC 2 project: one view page, one controller

View:

<%--Sign in form:--%> <% using(Html.BeginForm("SignIn", "Home", FormMethod.Post)) {%> <%= Html.AntiForgeryToken()%> <input type="submit" value="Sign in" /> <%}%> 

Controller:

 public ActionResult Index() { ViewData["status"] = "Index"; return View(); } [ValidateAntiForgeryToken] public ActionResult SignIn() { ViewData["status"] = "Signed In!"; FormsAuthentication.SetAuthCookie("username", false); return View("Index"); } 

[EDIT: simplified code example]

To recreate the exception, open two tabs without logging in - log in on the first tab and log in to the second tab.

The second tab will always throw a fake exception when I assume that the correct behavior would be to redirect to the page with the subscription (session sharing / authentication of the input login tab)

Any advice would be appreciated!

Cheers, dave

+5
source share
3 answers

The real answer to this problem is simply that you should not use the anti-fake token in the registration forms!

It makes no sense to "fake" the user in the login form - they are not logged in!

-2
source

Looking at the source code of MVC 2, it looks like the AntiForgeryToken hidden field enables the serialization of User.Identity.Name if you are logged in. On line 69, ValidateAntiForgeryTokenAttribute seems to then check your token with the current user .Identity.Name.

  string currentUsername = AntiForgeryData.GetUsername(filterContext.HttpContext.User); if (!String.Equals(formToken.Username, currentUsername, StringComparison.OrdinalIgnoreCase)) { // error: form token is not valid for this user // (don't care about cookie token) throw CreateValidationException(); } 

Since in your other tab that you just signed in the above code, the existing token that does not contain the user name .Identity.Name is canceled.

This could be fixed by adding !string.IsNullOrEmpty(formToken.Username) around this check, but I don’t know if this will open the security issues, which means it has a custom MVC 2 Build.

+5
source

You can use the same salt:

 <% using(Html.BeginForm("SignIn", "Home", FormMethod.Post)) {%> <%= Html.AntiForgeryToken("123")%> <input type="submit" value="Sign in" /> <%}%> <% using(Html.BeginForm("Protected", "Home", FormMethod.Post)) {%> <%= Html.AntiForgeryToken("456")%> <input type="submit" value="Do secret stuff" /> <%}%> 

And in your controller:

 [ValidateAntiForgeryToken(Salt = "123")] public ActionResult SignIn() { ViewData["status"] = "Signed In!"; FormsAuthentication.SetAuthCookie("username", false); return View("Index"); } [Authorize] [ValidateAntiForgeryToken(Salt = "456")] public ActionResult Protected() { ViewData["status"] = "Authed"; return View("Index"); } 

Do the same with the other token, but be sure to select the other salt.

0
source

Source: https://habr.com/ru/post/911707/


All Articles