I read that when using JWT, there is no need to protect against CSRF attacks, for instance: "since you are not relying on cookies, you don't need to protect against cross site requests".
However, something I do not understand: if I store the token in localStorage
(as I was advised on a tutorial of the same website), what prevents an attacker to forge a malicious request by reading my localStorage
instead of my cookies?
Since it was generated on the server side, I don't get how I could use a token for a client request without it being stored somewhere on the client.
If you put your JWTs in a header, you don't need to worry about CSRF. You do need to worry about XSS, however. If someone can abuse XSS to steal your JWT, this person is able to impersonate you.
The Bearer Authentication is a good way to prevent CSRF, as there is no way for an attacker to know the value of a valid token of an authenticated user. But some websites use both the cookies and bearer token as an authentication mechanism.
CSRF tokens prevent CSRF because without token, attacker cannot create a valid requests to the backend server. CSRF tokens should not be transmitted using cookies. The CSRF token can be added through hidden fields, headers, and can be used with forms, and AJAX calls.
A CSRF token is a secure random token (e.g., synchronizer token or challenge token) that is used to prevent CSRF attacks. The token needs to be unique per user session and should be of large random value to make it difficult to guess. A CSRF secure application assigns a unique CSRF token for every user session.
Strictly speaking, yes, anything stored in local/session storage (which I'll call HTML5 Storage) could be stolen in a cross-site scripting (XSS) attack. See this article.
There are a lot of moving parts to consider, however.
First, there are subtle differences in how HTML5 Storage and cookies are scoped with respect to JavaScript access.
HTML5 Storage is:
http://example.com
HTML5 storage cannot be accessed by JavaScript running on https://example.com
.http://example.com
HTML5 storage cannot be accessed by JavaScript running on http://sub.example.com
(you can do some tricks to get around this, however).Cookies are more loosey-goosey:
example.com
will go to both http://example.com
and https://example.com
unless it has the attribute secure
, in which case it will only be sent to https
.example.com
, then it will be sent to both example.com
and sub.example.com
. (This is the most confusing part of the cookie "spec", unfortunately, see this article).secure
cookie flag) unless the cookie has the httpOnly
attribute, in which case JavaScript will not be able to read it.Second, since cookies are marked with a domain, when a request is made to a server, the browser will send all-and-only cookies with a matching domain, regardless of the domain of the page that originated the request.
The last part is how a CSRF attack is accomplished (the same-origin policy only helps so much). The OWASP page on CSRF is a good resource for learning how these kinds of attacks work.
The reason storing an authentication token in local storage and manually adding it to each request protects against CSRF is that key word: manual. Since the browser is not automatically sending that auth token, if I visit evil.com
and it manages to send a POST http://example.com/delete-my-account
, it will not be able to send my authn token, so the request is ignored.
With the above in mind, whether to use a cookie or HTML5 Storage becomes a series of tradeoffs:
Storing the authen token in HTML5 Storage means:
(-)
Risk of it getting stolen in an XSS attack.(+)
Provides CSRF protection.(-)
Must manually modify each request going to the server, limiting you to SPA (eg AngularJs) web applications.On the other hand, if you store the authn token in a cookie marked httpOnly
and secure
, then:
(+)
The authn token cannot be stolen by XSS.(-)
You will have to provide CSRF protection yourself. Implementing CSRF protection is easier in some frameworks than others.Which option is better depends on your needs.
httpOnly
secure
option.When using token based authentication you have to manually associate the token with the request. Contrary to cookies, tokens are not set automatically by the browser thus not susceptible to csrf
attacks.
While this approach is safe from csrf
attacks, it is susceptible to xss
attacks.
A minimal effort improvement would be to use session storage
instead of local storage
since session storage
data gets purged after the user closes the tab/browser.
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