How does a xsrf token cookie protect against csrf? - cookies

Wouldn't a malicious site be able to read the cookie using xss cookie stealing and put it in the header of an ajax request?

Of course, if the site is vulnerable to xss, it's also vulnerable to csrf, but that's the smaller issue then.
If there is no xss though, the attacker has no way to read the token due to the same origin policy.

Related

Dj rest auth using JWT Token stored in HttpOnly cookies

I'm making a Django Rest Framework application with a JWT authentication with tokens stored in HttpOnly cookies. Authentication is performed via reading the access cookie. I'm using a dj-rest-auth library for this purpose, but I'm a little confused of the security aspect of such method. Knowing that having authentication data stored in cookies can be used to perform CSRF attack, how can one protect their web against such attacks for a specific case I've described above? All cookies are set to be SameSite=Lex.
Do I need to also send X-CSRFTOKEN header obtained from the backend? That would mean that every request to the api will need to have that header. What should be the optimal setup having all those libraries?
The OWASP foundation has created a detailed cheat-sheet on how to prevent from CSRF attacks: https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html
Two things worth remembering:
CSRF is a concern only for data-changing requests, so POST/PUT/PATCH/DELETE methods. An attacker performing a CSRF attack can't read the response from the server, so GET requests are not your concern.
The most common way of preventing CSRF is with a csrf token. The server should create the token for the user's session and the token is saved in frontend, but not in a cookie. Then you send that token either in a header or as part of the request body. The server then validates that the token is the same as the one it has for that user session.
If you don't want to persist the token in your server, you can additionally save it in a cookie. So the frontend will keep the token in two places - one in memory/in a hidden form field/etc. and another one in the cookie. Then the server can check if the value from the cookie matches the value from header/body.
All cookies are set to be SameSite=Lex.
Do I need to also send X-CSRFTOKEN header obtained from the backend?
SameSite is not supported by older browsers. As per caniuse, it is supported by 90% browsers in use globally.
Arguments AGAINST implementing CSRF tokens:
I think it's a low risk. If you think your users will be among those 90%, then don't bother with CSRF tokens.
Since you're using JWTs, I assume the frontend is going to be a modern SPA app. If you don't expect it to run on older browsers, then, again, don't bother with CSRF tokens.
Arguments FOR implementing CSRF tokens:
Lax offers no protection on GET requests. You'll have to make sure, today and in future as well, that you never modify server state in GET requests. If you implement CSRF tokens, you'll have one less thing to worry about. Or you can also use SameSite=Strict value.
My opinion:
Personally, I'd just implement CSRF tokens. It's a one time setup and most frameworks already take care of this. So, why not?
P.S.: I'm not sure if you've a typo there, but it is Lax, not Lex.

Why store Refresh Token in a HTTP Only Cookie Prevent From CSRF Attack?

I just read an article from this
https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/
In summary, they recommend to store JWT Access Token in memory (as a variable in JavaScript for example) and Refresh Token in HTTP-Only Cookie.
They said:
But by persisting our session indirectly via a refresh token, we
prevent a direct CSRF vulnerability we would have had with a JWT
token.
But is it store Refresh Token in a HTTP-Only cookie still vulnerable to CSRF Attack? For example, evilsite.com can make request to /refreshtoken endpoint to get new JWT access token. What I understand about HTTP-Only cookie is the cookie can't be read from JavaScript but it will automatically be sent whenever make a HTTP request like how the evilsite.com does. (Correct me if i'm wrong).
Refresh token in a cookie and access token in memory can be a good model if used with care. Hopefully some better guidance will be made available in standards such as BFF-TMI.
The cookie should have these properties and the SameSite property will mean evilsite cannot send it, so that it is good from a CSRF viewpoint.
HTTP Only
Secure
AES256 Encrypted
SameSite=strict
OWASP's CSRF Guidance seems to recommend using both SameSite and CSRF tokens together as the preferred option.
Out of interest here is how I'm implementing things in an SPA Code Sample at the moment - in case it is useful to borrow ideas from:
SPA OAuth Code
Back End API OAuth Code
I may change my mind a little as guidance in this area evolves.
HIGH SECURITY OPTION?
The current concensus is that the following option is preferred in terms of security, though I am hoping risks and mitigations become better documented over the coming year:
Keep access tokens out of the browser completely
Proxy all API calls via the 'back end for front end'
See this insightful 2021 video
This option may add complexity in some areas though, and could also limit capabilities in some scenarios.
As is often the case with security, there are trade-offs with other factors, and the solution chosen may depend on data sensitivity and what stakeholders care about.

Using JWT stored in HTTPonly & secure cookie: Vulnerable to CSRF. but not to XSS?

I understood webstorage is vulnerable to xss
And Cookie to CSRF also makes sense
What makes me puzzled is that it seems like implicitly said that cookie is not vulnerable to xss, but isn't it also vulnerable to xss?
If I can run a script on other's browser, I think I might be able to just send request to server & get important data cause browser automatically attach cookies & I dont' need to do anything to get authenticated.
If a cookie is set with the httpOnly flag, it cannot be accessed from Javascript (injected js cannot read or write such cookies), so it is not possible to steal the cookie value if it's httpOnly. This is very relevant for a session cookie. In this case, this cookie is not affected by XSS. Note that this is solely because of the httpOnly flag - cookies without httpOnly are affected by XSS, because they are accessible to Javascript.
Any cookie (regardless of flags*) will still be sent with any request to the server it was received from, but that is the realm of csrf, actually, it is the fundamental problem in csrf. If anybody (from any website) makes a request to a server, any cookie for that server will be sent, and the attacker can exploit csrf if there is no protection. That's why you need protection against csrf if you have cookie-based authentication.
Also note that if the page is vulnerable to XSS, than any csrf protection is useless, because xss can be used to read the token, wherever it is stored.
*Sidenote: the new SameSite cookie flag changes this, but that is only supported by Chrome.

JWT + cookies + HTTPS + CSRF

I already worked with JWT on mobile app but I will implement it on a website for the first time for the authentication and I have a little thing I still didn't understood :
if I use JWT token with localStorage, XSS attacks are possible
if I use JWT token with cookies, CRSF attacks are possible
..., but if I use JWT token over HTTPS with httpOnly+secure cookies and a token lifetime of 1 month, are CSRF attacks still possible in this case ?
I see all over the web for custom token with cookie or custom token with localStorage or JWT but I didn't explicitly get the answer of httpOnly+secure cookie + JWT + HTTPS + the need of CSRF.
If you are using JWT as an authentication token, it should be stored as a cookie marked httpOnly and secure, as apposed to using Local/Session Storage. As you mention, this protects against XSS attacks, where we are concerned about malicious JavaScript being injected into our page and stealing our session token.
A cookie marked httpOnly cannot be read by JavaScript, so it cannot be stolen in an XSS attack.
Local/Session Storage, however, can be read by JavaScript, so putting the session token there would make it vulnerable to an XSS attack.
However, making the session token cookie httpOnly and secure still leaves you vulnerable to CSRF attacks. To see why, remember that cookies are marked with the domain from which they originated, and the browser only sends cookies that match the domain to which the request is being sent (independent of the domain of the page the request was sent from). For example, suppose I'm signed into stackoverflow.com in one tab, and in another tab go to evil.com. If evil.com makes an ajax call to stackoverflow.com/delete-my-account, my stackoverflow authentication token cookie will be sent to the stackoverflow server. Unless that endpoint is protecting against CSRF, my account will be deleted.
There are techniques for preventing CSRF attacks. I would recommend reading this OWASP page on CSRF attacks and preventions.

LocalStorage and Xss

Can localstorage value of a site be overwritten by xss(cross-site-scripting)? As far as I have verified in chrome and firefox, the localstorage value of a site is not accessible by a different site. Can anyone tell me whether the localstorage value can be read/write from a different domain in the browser by xss ?
Nowadays many websites, add third-party js libraries for Analytic, A/B testing, Marketing tools, Heat maps and ... You may be sure about your codes but if one of these scripts, is vulnerable then you should expect XSS attack easily and in this case, It can grab your localStorage. Don't use local storage for session identifiers or sensitive tokens. Stick with cookies and use the HTTPOnly and Secure flags. To prevent CSRF attacks on Cookies, almost all requests include one or both of: Origin Header and Referer Header. CSRF can be partially prevented by checking the HTTP Referer and Origin header from your API. CSRF attacks will have Referer and Origin headers that are unrelated to your application.
Javascript coming from reflected XSS or similar can do whatever normal JS can do on the domain where the XSS exists. So if example.com has stored things in localStorage and example.com also has an XSS flaw, then that XSS vuln can be used to extract or overwrite users data in localStorage. You could even use a reflected XSS, which exploits a DOM-based XSS using data from localStorage, meaning a client side persistent XSS.
Web storage (local and session) follow single origin policy. So it XSS access to web storage is not possible.