How does the MVC anti forgery token survive between web server restarts?
Asked Answered
M

1

9

I've implemented anti-forgery protection using the ValidateAntiForgeryTokenAttribute in MVC 5. It is working fine, but in the future we may move to more of a "web farm" approach to hosting. If I run my application in development and go to a form, restart the web server (by restarting the app in Visual Studio) and then submit a form, it doesn't throw the System.Web.Mvc.HttpAntiForgeryException.

Our application doesn't use any other session state. Can someone help me understand how my server picks up where it left off? I'm not defining a machineKey in my web.config, or anywhere else that I can find. Does it have something to do with running in a development environment?

The only references I can find to this are for earlier versions of MVC, so I'm wondering if this is solved in a different way now.

I'm glad this functionality works, but I need to understand why.

Mcphee answered 23/7, 2014 at 20:49 Comment(1)
For an explanation of what's going on behind the scenes: levelup.gitconnected.com/…Hustler
A
3

The server itself isn't remembering anything; it doesn't have to.

The two things at work here are:

  • The form hidden input
  • A cookie

This means that if the user visits a page with an AntiForgeryToken on it, then the server restarts, it's no problem because the user's and the form's __RequestVerificationToken are still the same as they were.

The actual security token is a hashed key that is stored inside the AntiForgeryToken object. This object is serialised to Base 64 and that is what you see when you look at the values of the __RequestVerificationToken. Since the security keys are stored each time, even if the server resets the values are still inside those objects. The keys are then retrieved and compared in order to validate the tokens.

There is no decryption during this process. The tokens are deserialised, the security keys read and then compared. Since the security keys are not encrypted, but are rather hashed, then they cannot be decrypted; only compared.

Amador answered 23/7, 2014 at 22:48 Comment(4)
Thanks for that. I'm aware that the two values are compared, but I think the encryption key used to decrypt the values is supposed to be regenerated when IIS is restarted. It shouldn't be able to decrypt the values after that happens because the key is new.Mcphee
Ah, I see what you're asking. Great question. I'll update my answer.Amador
I appreciate the time you took to write that answer, but I'm not sure it is correct. This Microsoft website says that "the payloads of the anti-XSRF tokens are encrypted and signed". Here is the URL to the page: asp.net/mvc/overview/security/…. I believe what is happening in my case is that the MachineKey used to encrypt and decrypt doesn't actually change between restarting the website or app pool like it used to. I can't find documentation to support that yet, but that's what I think is happening.Mcphee
No problem. I'm only just barely understanding the logic involved. The underlying algorithms are hash algorithms (something like HMAC-SHA1). However I still stand by what I believe is the most important statement which is that the keys are stored in the tokens which are stored in the cookie and the form input. This means that they can be retrieved and compared. Hopefully someone can verify or clarify further (Micrsoft ^^).Amador

© 2022 - 2024 — McMap. All rights reserved.