Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If I add multiple forms in a single page, do I need to add separate Anti-Forgery Tokens in each form?

If the answer is yes then how would ASP.NET MVC find out that which token was linked to which form and how to validate it?

I've seen it is creating two separate tokens for each form.

like image 430
neebz Avatar asked May 04 '11 18:05

neebz


2 Answers

There is nothing specific that you need to do in this case. ASP.NET MVC will simply reuse the same value for all forms so it doesn't need to know which form sent the request in order to validate it. Simply put an Html.AntiForgeryToken() in each form and decorate each controller action you are posting to with the [ValidateAntiForgeryToken] attribute and you should be OK.

like image 132
Darin Dimitrov Avatar answered Oct 08 '22 17:10

Darin Dimitrov


There is a great article here I pointed out some important sections.

In a nutshell, If a token can be deserialized from the request’s cookie collection, it’ll reuse that token instead of generating a new one. If a token doesn’t exist in the cookie collection, it’ll instantiate a new instance of “AntiForgeryToken” and randomly generate a new 16 byte array to represent the token.

public AntiForgeryToken GetCookieToken(HttpContextBase httpContext) {     HttpCookie cookie = httpContext.Request.Cookies[this._config.CookieName];      if (cookie == null || string.IsNullOrEmpty(cookie.Value))         return (AntiForgeryToken) null;      return this._serializer.Deserialize(cookie.Value); } 

After generating the first token and saving it to the cookie collection, all subsequent calls to the helper method “Html.AntiForgeryToken()” will follow the same steps and reuse the existing token from the cookie collection instead of generating a new value.

Since it is a session cookie, this means the anti-forgery token’s value is generated only once during a browser session and is reused for all subsequent calls.

So why are the hidden field values different from one another if they are reusing the same token?

So while the encrypted values may look different, the decrypted values are the same.

byte[] one = MachineKey45CryptoSystem.Instance.Unprotect("iAdQj5D0qrMuTggD8WpnOZPlVOfHg_qmPIEjnULAYd1h56cV2cL51rcaY8_UgxQbav5_6KTAtyE52ir1X6GmaS9ZPgw1"); byte[] two  = MachineKey45CryptoSystem.Instance.Unprotect("Shvi8Bxe6-a8zfCfDGnxkaC-IETsbjkR9iIylwn-2VRWQ-GtQkdowdFw1biU7dN3j-xPJZHYQPe-hNfWspYjy_ZcCCY1"); byte[] three = MachineKey45CryptoSystem.Instance.Unprotect("ZhaVFngUMLo88jmTIx___BTWlYFyKh1GalwEeffRl0-o3Gu7_m98k6aQjO7IysZIdXxVx6TqL6QIfX19Uwq3Ia6dghA1"); 

Comparing all three byte arrays reveals they are identical.

like image 31
erhan355 Avatar answered Oct 08 '22 18:10

erhan355