Bearer tokens and CSRF
Asked Answered
W

2

6

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?

Worse answered 26/5, 2017 at 9:4 Comment(0)
C
4

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.

Cyrene answered 29/5, 2017 at 9:18 Comment(3)
I downvoted this answer because it conflates a social engineering attack with CSRF. "Say someone tricks your users to click a link that triggers an action in your SPA" directly conflicts with "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." The first is a social engineering (or like, a permissions boundary violation in a user-agent) attack, and the latter is CSRF as traditionally defined. See also security.stackexchange.com/a/166798/199032 and security.stackexchange.com/a/170414/199032Vaish
@Brad I agree it's poorly worded. Got a suggestion? Like "Say someone causes the browser to issue a request on behalf of the user" or something like that?Cyrene
@Brad either way, my emphasis was definitely not on social engineering. To be susceptible to a CSRF attack, the user must either visit a site that attacks a particular application, or include some kind of script in the application itself (XSS). Either way, the origin is irrelevant, and I still stand by my answer. I will revisit it and reword when possible.Cyrene
P
5

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:

  1. 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.

  2. 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.

Prestidigitation answered 1/6, 2017 at 8:46 Comment(3)
Regarding #1: a SPA generally works with AJAX requests, who can't access HttpOnly cookies.Cyrene
That's correct. That is why I described two cases (HttpOnly and not). I saw a couple of times cookies used as local storage and as long as question mentioned header authentication I suspected it implied extraction of token from cookiesPrestidigitation
I see that I misinterpreted you. #1 is exactly the case of ordinary cookies authentication when cookies (with token, presumably) are sent together with Ajax request. So no token extraction here and csrf vulnerability.Prestidigitation
C
4

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.

Cyrene answered 29/5, 2017 at 9:18 Comment(3)
I downvoted this answer because it conflates a social engineering attack with CSRF. "Say someone tricks your users to click a link that triggers an action in your SPA" directly conflicts with "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." The first is a social engineering (or like, a permissions boundary violation in a user-agent) attack, and the latter is CSRF as traditionally defined. See also security.stackexchange.com/a/166798/199032 and security.stackexchange.com/a/170414/199032Vaish
@Brad I agree it's poorly worded. Got a suggestion? Like "Say someone causes the browser to issue a request on behalf of the user" or something like that?Cyrene
@Brad either way, my emphasis was definitely not on social engineering. To be susceptible to a CSRF attack, the user must either visit a site that attacks a particular application, or include some kind of script in the application itself (XSS). Either way, the origin is irrelevant, and I still stand by my answer. I will revisit it and reword when possible.Cyrene

© 2022 - 2024 — McMap. All rights reserved.