ASP.NET Core antiforgery token that works over multiple tabs?

105 Views Asked by At

I recently migrated our app to .NET 8 and I'm trying to get our previously working antiforgery tokens to work. Most of it is working fine.

However, whenever opening multiple browser tabs we start getting validation errors saying the anti forgery token is not valid. I found this blurb in the Microsoft documentation stating that the synchronizer pattern is going to invalidate the antiforgery token whenever you open a new tab. It then suggests considering alternative CSRF protection patterns if this poses an issue.

However, it does not demonstrate other patterns in the documentation!

It seems to me that users using multiple browser tabs is commonplace now, so what other patterns are there? In every case they show, you are essentially creating a token, sending it down to the JavaScript and sending it back up in requests... what other pattern is even possible with an antiforgery token? I don't get it.

https://learn.microsoft.com/en-us/aspnet/core/security/anti-request-forgery?view=aspnetcore-8.0#antiforgery-in-aspnet-core

enter image description here

1

There are 1 best solutions below

0
TonyE On

After more searching, it seems the solution is not to use an AntiForgery token at all, and use a different pattern entirely. There are a few listed in the OWASP cheat sheet for CSRF, although only one other method is not frowned up. That method is the Signed Double Submit Cookie method as described here, which I will pursue.

https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html

ALTERNATIVE: Using A Double-Submit Cookie Pattern¶ If maintaining the state for CSRF token on the server is problematic, you can use an alternative technique known as the Double Submit Cookie pattern. This technique is easy to implement and is stateless. There are different ways to implement this technique, where the naive pattern is the most commonly used variation.

Signed Double-Submit Cookie (RECOMMENDED)¶ The most secure implementation of the Double Submit Cookie pattern is the Signed Double-Submit Cookie, which uses a secret key known only to the server. This ensures that an attacker cannot create and inject their own, known, CSRF token into the victim's authenticated session. The system's tokens should be secured by hashing or encrypting them.

We strongly recommend that you use the Hash-based Message Authentication (HMAC) algorithm because it is less computationally intensive than encrypting and decrypting the cookie. You should also bind the CSRF token with the user's current session to even further enhance security.

EMPLOYING HMAC CSRF TOKENS¶ To generate HMAC CSRF tokens (with a session-dependent user value), the system must have:

A session-dependent value that changes with each login session. This value should only be valid for the entirety of the users authenticated session. Avoid using static values like the user's email or ID, as they are not secure (1 | 2 | 3). It's worth noting that updating the CSRF token too frequently, such as for each request, is a misconception that assumes it adds substantial security while actually harming the user experience (1). For example, you could choose one of the following session-dependent values: The server-side session ID (e.g. PHP or ASP.NET). A random value (e.g. UUID) within a JWT that changes every time a JWT is created. A secret cryptographic key Not to confuse with the random value from the naive implementation. This value is used to generate the HMAC hash. Ideally, store this key as an environment variable. A random value for anti-collision purposes. Generate a random value (preferably cryptographically random) to ensure that consecutive calls within the same second do not produce the same hash (1).