Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.Net MVC cookies - tamper resistant?

So I was reading a neat article I found on /r/netsec:

https://paragonie.com/blog/2015/05/using-encryption-and-authentication-correctly

One thing that really threw me for a loop is that one could flip a bit in an encrypted cookie and actually have a meaningful change in the contained data.

Making sure all traffic goes over SSL is easy enough (this isn't a question about secure transport), but this got me really thinking about message integrity and how to see if the original cookie has been tampered with. Typically I would store only the authenticated user ID in the cookie and handle all the other stuff behind my firewall. What if I could tamper with that cookie to change the user ID from the client side? The above article indicates that this is possible, as well as offering suggestions to solve this problem using preferably libsodium. I know of this library (haven't used it myself), but that leads me further down the rabbit hole in my thinking that something external to ASP's built-in security mechanisms are needed.

Regarding built-in ASP security specifically, do I need to do anything special not already implemented in the standard way of handling cookie security (letting OWIN do its thing or using FormsAuthentication.Encrypt)? If not, how is message integrity handled under the hood?

Further reading led me to this HttpSecureCookie class on code project: http://www.codeproject.com/Articles/13665/HttpSecureCookie-A-Way-to-Encrypt-Cookies-with-ASP

The above indicates using the machine key to make a cookie tamper proof, but I am unclear as to exactly HOW it makes it tamper proof. How would this prevent the malicious user from doing that bit flipping indicated in the original article to an encrypted cookie?

like image 277
Bill Sambrone Avatar asked May 06 '15 15:05

Bill Sambrone


People also ask

Are cookies tamper proof?

To encrypt or sign cookies and reject tampered cookies, you need to enable cookie security using the following steps: Go to the SECURITY POLICIES > Cookie Security page. Select a policy from the Policy Name list. In the Cookie Security section, select the desired Tamper Proof Mode, either Encrypted or Signed.

What method can be used to ensure that the contents of a cookie haven't been tampered with by the user?

Simply set the forms authentication protection method to Encryption and validation . This will protect against bitflipping attacks as the signature will not match once a bit is flipped.

How do I protect cookies in asp net?

Mark cookies as Secure Cookies. Add( new HttpCookie("key", "value") { Secure = true, }); That's it! Cookies are now only sent over HTTPS, making it impossible to intercept any cookies accidentally sent over HTTP (you still want to eliminate those calls if any).

Are ASP Net cookies encrypted?

The data-protection system uses symmetric-key encryption to protect data. A key containing random data is used to encrypt the data, and the same key is used to decrypt the data. The ASP.NET Core data-protection system assumes that it will be the same app or application decrypting the data as encrypted it.


1 Answers

Simply set the forms authentication protection method to Encryption and validation.

This will protect against bitflipping attacks as the signature will not match once a bit is flipped. Validation means the message is signed.

How does validation work?

The validation algorithm can be set in web.config in the validationAlgorithm attribute of the machineKey element.

By default it uses HMACSHA256 which is a SHA-256 hash applied using the HMAC construct.

The hash signs the cookie - if the cookie value changes, the hash will no longer match. As an end user does not know the secret, they cannot change the cookie value.

e.g. Try on here to generate a SHA-256 HMAC for message foo with the secret secret.

This should give you: 773ba44693c7553d6ee20f61ea5d2757a9a4f4a44d2841ae4e95b52e4cd62db4

Note that if you change the foo to something else, the hash will be different. This is how a cookie can be protected from tampering. This cookie would be set as follows.

Set-Cookie: id=foo&hash=773ba44693c7553d6ee20f61ea5d2757a9a4f4a44d2841ae4e95b52e4cd62db4

Notice that the value is in the clear, but the hash signature prevents any tampering. This is validation only.

With the encryption and validation option foo would be encrypted first and the signature would prevent any bit flipping. This enables values to be stored in private from the end user.

If you're implementing this outside of Forms Authentication, remember though to store some type of expiry date in the cookie and include this in the signature. This date can be checked server side. Forms authentication does this by default.

Otherwise, a user could make note of a valid cookie value. Say they are given administrator access for one day and the following cookie is issued:

username=admin&hash=71b3ba92493e92ce3c60042988e9de428f44b35a6be61c8da99fa43f950d3056

The next day when the administrator access is revoked, all the user would need to do is use a cookie editor to set their cookie to the above value and they would have administrator access to the system again.

To fix this you would issue a cookie like so:

username=admin&expiry=20150508100000&hash=e38a3a003b30ceb9060165d19bb8d2a2bca6c7c531a37e888448ca417166db3a

This has the expiry date in the cookie, which is signed in the hash. Any attempt to modify the expiry date will result in a HMAC mismatch, and the user will not have access. This will prevent any tampering with the cookie expiry date or any recreation client-side.

What are our other don't-mess-with-my-cookie options if not using forms authentication?

Another method is to store a completely random, cryptographically secure generated string and set that as the cookie value. On your server, store it hashed with SHA-2 (no need for salt) and lookup this value to retrieve details about the user's session. Of course this has some more overhead. The advantage is that sessions can be killed server side by deleting the entry.

This can be done with Forms Authentication too, however you would need to implement a custom provider.

like image 54
SilverlightFox Avatar answered Oct 10 '22 19:10

SilverlightFox