Replies: 1 comment 5 replies
Per-request tokens are safer because they ensure that a user cannot successfully submit a request to an endpoint unless they have been provided a per-request token for that endpoint. Without per-request tokens, users can successfully submit a request to any endpoint, since the CSRF token is the same for all endpoints. Admittedly, the extra security goes beyond what you would typically think of as CSRF protection. Traditional CSRF protection focuses on protecting users from forms on other websites. Per-request tokens provide protection against users accessing things they were not explicitly given access to on the site itself.
Certainly it is easier to use per-request tokens on traditional apps. It's possible to use them with SPAs as long as you provide the per-request tokens appropriately for the SPA to use, though it is more work (SPAs in general are more work).
As explained above, per-request tokens offer additional protection, though the protection may be considered as going beyond traditional CSRF protection.
I think it's still relevant, even if it isn't as relevant now as it was then. Can I use shows Global 93.47% for Sec-Fetch-Site, so support is far from universal: https://caniuse.com/?search=Sec-Fetch-Site
IMO, the security benefits of route_csrf are significant. I've seen multiple production cases that would have been actual security vulnerabilities were it not for the security provided by per-request CSRF tokens. Traditional CSRF tokens also work in all browsers. So I think the existing documentation is good. If you have additional questions or think additional changes are needed considering the above, please let me know. |
Uh oh!
There was an error while loading. Please reload this page.
Here's what the documentation currently says about this plugin:
Why per-request tokens would make it any safer? The main reason to mask or replace the CSRF token is to prevent against BREACH attacks but by using the Sec-Fetch-Site header as a CSRF protection mechanism the app won't be vulnerable to BREACH since there's no token to be reflected.
Per-request tokens can work well on traditional HTTP apps where a user is presented a form, submits a button, gets another page and so on, all on a single tab session. It doesn't work well for SPA apps performing POST requests concurrently, for example.
Sec-Fetch-Site has been implemented since 2023 in all relevant browsers, 3 years ago. It's not only much simpler to implement, but it's also faster to process and pretty safe to use. It's not sucsectible to BREACH attacks either. And yet the documentation currently describes it almost as an unsafe method to prevent CSRF, while it should be considered the preferred approach IMO these days.
I don't really see any security trades, or at least they're not explained well enough. For example, if the CSRF token doesn't change, the attacker must know the token in order to perform any POST requests to the server. How could the attacker know about the user's CSRF token? I can only think of some XSS vulnerability allowing the attacker to inspect the CSRF token. If such vulnerability exists, the application has bigger problems to worry about. Also, if it exists, the attacker would be able to read the token from the form anyway no matter if it's unique for that request.
The first point was relevant in 2023, but I don't think it remains relevant in 2026, 3 years later. See:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Sec-Fetch-Site#browser_compatibility
If your app is deployed over HTTP instead of HTTPS, you can't be serious about security either. There's no reason for HTTPS not to be used for all apps these days.
I'd say that if your application would want to be accessible by other sites from other domains, then it might be a use case for preferring
route_csrfoversec_fetch_site_csrf. However, if the third-party application on a separate domain should be allowed to talk to the Roda server, maybe it would make more sense for the backend to adopt JWT token authentication instead of a cookie-based one. Anyway, theroute_csrfplugin would be only one of the available options to allow for apps to share a given CSRF token. Most likely there are better solutions available for such cases, that should be investigated on a case-per-case basis. This is not a common-enough pattern in order to justify preferringroute_csrfoversec_fetch_site_csrf.I'd love to hear your thoughts about it.
All reactions