We are building 3 different applications MVC application, API, SPA (not Angular) with ASP.NET Core. All the actions in this application are only for authorized users. That's why we protect them with IdentityServer.
We use a cookie to store the value of the bearer token. I understand that the value of the cookie gets sent automatically to the server. But because it should be added as an authorization header this is not done by the browser automatically.
Does this mitigate the possibility of a CSRF attack? Or is CSRF still possible with bearer tokens and do we need to add CSRF tokens anyway?
Yes, you still need CSRF tokens.
If your SPA or MVC application will send requests to your API based on a GET or POST action by the user, you still need CSRF tokens.
Say someone tricks your users to click a link that triggers an action in your SPA, or that posts to your MVC application, the application will happily comply and send the bearer token stored in the cookie as a request header, just as when the user has clicked a link in the application itself.
That's the whole point of CSRF, an attacker crafts a request just as if the user has invoked an action in your web application.
If I understand you right both MVC and SPA authenticate the user with Identity Server and store tokens in cookies primary for accessing API.
In general, there are two cases here:
Your cookies are HTTP only (not accessible at frontend). Then you send cookies to MVC and SPA server sides that extract cookies and send request further to API. This case you are as vulnerable to CSRF as usual since you do effectively authenticate with cookies and consequent token extraction and bearer authentication against API happens based on exclusively result of automatic cookie authentication.
Cookies are accessible at frontend. This case you can read them with Javascript and send bearer authenticated request to MVC and SPA server side (for passing further to API) or directly to API making all backends to ignore cookie content as potentially compromised. This case you are not vulnerable to CSRF (as you pointed out bearer authentication header must be constructed explicitly). However, you are vulnerable to XSS (cross site scripting): any code injected into your page using either security hole in data validation/sanitation or simply third party dependency can read cookies and re-send them to any server. This case is very much alike using local/session storage so any articles describing their vulnerabilities apply to your scenario as well (e.g here).
So you must take a choice between CSRF or XSS as the main attack.
CSRF can be prevented completely with anti-forgery tokens but if you fail to do it attack is very easy to organize.
XSS is in theory hard to prevent completely in modern development due to a multitude of 3rd party libraries you use (another XSS attack vector - input sanitation is not so much of a problem as a rule since most of MVC framework do it for you by default like ASP NET Core). However, you have a fair chance of avoiding it which makes this option a reasonable choice in many cases e.g. Auth0 recommends it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With