Best approach for validating anti forgery token? - security

Where should I put anti-forgery token in the request? (as per the latest standards)
Header
Form Body

Related

Able to access an API without having any values in Header part of JWT Access Token

I am testing a web application that uses the OAuth mechanism to authorize and access the APIs. The OAuth uses RS256 algorithm to sign the tokens. I noticed that I am still able to access the API when I pass the JWT token with null 'Header' value and without 'Verify Signature' section in JWT token.
Example:
Orginal JWT Token - <header>.<payload>.<signature>
Modified JWT Token - .<payload>
As per the standard security best practices, the header should not accept "none" algorithm and the recommended algorithm should be either HS256 or RS256. But in the above case, the APIs are successfully authorized with null header value. I even tried with "none" algorithm in the header and still the APIs are accepted.
Is it a security issue as the algorithm is not validated in the API? May I know how an attacker can use this scenario to exploit the API.
If you're changing the header part or signature part (e.g. not sending them), and the API still accepts the token, then it means that the API does not validate the signature at all. It means that you can put anything in the payload, encode in base64 and the API will accept it as a valid token.
It's not a "security issue", it's just plain wrong implementation.

Why does using JWT refresh tokens protect against CSRF during authentication?

I have read a few articles regarding JWT refresh tokens, and how/why they are used. One thing i have seen mentioned here: https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/#persistance and here: https://dev.to/cotter/localstorage-vs-cookies-all-you-need-to-know-about-storing-jwt-tokens-securely-in-the-front-end-15id
is that using refresh tokens mitigates against CSRF attacks. The first article states:
The refresh token is sent by the auth server to the client as an HttpOnly cookie and is automatically sent by the browser in a /refresh_token API call.
Because client side Javascript can't read or steal an HttpOnly cookie, this is a little better at mitigating XSS than persisting it as a normal cookie or in localstorage.
This approach is also safe from CSRF attacks, because even though a form submit attack can make a /refresh_token API call, the attacker cannot get the new JWT token value that is returned.
The second article says something similar:
Although a form submit to /refresh_token will work and a new access token will be returned, the attacker can't read the response if they're using an HTML form
I am struggling to see how this would prevent CSRF attacks as I am thinking the following:
A request to /refresh token from another domain to the users will return new JWT token to the user. I am going to assume this is stored in a HttpOnly cookie (as is done in the first article)
As CSRF does not involve any injection of javascript and the cookie it httpOnly, the attacker can't read the value of the new JWT token.
However, if the JWT token is stored in a cookie again, surely a CSRF attacker can just send another request using this new cookie, with the new JWT token sinde?
If my understanding is correct, I am struggling to see how CSRF attacks are prevented by using refresh tokens. Can someone please explain exactly why refresh tokens prevent CSRF attacks, and why the CSRF attacker can't just use the new JWT the user would receive for future attacks?
It seems to me that the thing that would actually be preventing a CSRF attack would be the use of a sameSite cookie, or maybe using some sort of anti-forgery token.
The new jwt would not be returned from the identity provider as a cookie. That would not make much sense as the client on a different origin would not be able to read it. Instead, the token is passed in the response body, or even the url (usually not the token in that case, but let's not delve into that).
So the idp has its httpOnly cookie to authenticate the user, issues a new token in some way that is not a cookie, and the client stores the token for the appropriate origin (not the idp) in say localstorage. This way, any call to the resource server is not vulnerable to csrf, because the token needs to be explicitly be added from localstorage. The idp can be called by attacker.com to issue a new token ("csrf"), but attacker.com will not have access to the token due to the same origin policy, so it's not exploitable.
Note that even if the new token is returned as a cookie for the idp and read from there by the client, it's still ok, because the idp will do nothing with that token, and the resource server (~api) will not receive it automatically.

Should JWT be stored in localStorage or cookie? [duplicate]

This question already has answers here:
Where to store JWT in browser? How to protect against CSRF?
(7 answers)
Closed 2 years ago.
For the purpose of securing REST API using JWT, according to some materials (like this guide and this question), the JWT can be stored in either localStorage or Cookies. Based on my understanding:
localStorage is subjected to XSS and generally it's not recommended to store any sensitive information in it.
With Cookies we can apply the flag "httpOnly" which mitigates the risk of XSS. However if we are to read the JWT from Cookies on backend, we then are subjected to CSRF.
So based on the above premise - it will be best if we store JWT in Cookies. On every request to server, the JWT will be read from Cookies and added in the Authorization header using Bearer scheme. The server can then verify the JWT in the request header (as opposed to reading it from the cookies).
Is my understanding correct? If so, does the above approach have any security concern? Or actually we can just get away with using localStorage in the first place?
I like the XSRF Double Submit Cookies method which mentioned in the article that #pkid169 said, but there is one thing that article doesn't tell you. You are still not protected against XSS because what the attacker can do is inject script that reads your CSRF cookie (which is not HttpOnly) and then make a request to one of your API endpoints using this CSRF token with JWT cookie being sent automatically.
So in reality you are still susceptible to XSS, it's just that attacker can't steal you JWT token for later use, but he can still make requests on your users behalf using XSS.
Whether you store your JWT in a localStorage or you store your XSRF-token in not http-only cookie, both can be grabbed easily by XSS. Even your JWT in HttpOnly cookie can be grabbed by an advanced XSS attack.
So in addition of the Double Submit Cookies method, you must always follow best practices against XSS including escaping contents. This means removing any executable code that would cause the browser to do something you don’t want it to. Typically this means removing // <![CDATA[ tags and HTML attributes that cause JavaScript to be evaluated.
A timely post from Stormpath has pretty much elaborated my points and answered my question.
TL;DR
Store the JWT in cookies, then either pass the JWT in the Authorization header on every request like I've mentioned, or as the article suggests, rely on the backend to prevent CSRF (e.g. using xsrfToken in case of Angular).
Do not store your token in LocalStorage or SessionStorage, because such token can be read from javascript and therefore it is vulnarable to XSS attack.
Do not store your token in Cookie. Cookie (with HttpOnly flag) is a better option - it's XSS prone, but it's vulnarable to CSRF attack
Instead, on login, you can deliver two tokens: access token and refresh token. Access token should be stored in Javascript memory and Refresh token should be stored in HttpOnly Cookie. Refresh token is used only and only for creating new access tokens - nothing more.
When user opens new tab, or on site refresh, you need to perform request to create new access token, based on refresh token which is stored in Cookie.
I also strongly recommend to read this article: https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/
To help prevent CSRF attacks that take advantage of existing cookies, you can set your cookie with the SameSite directive. Set it to lax or strict.
This is still a draft and as of 2019 is not fully supported by all current browsers, but depending on the sensitivity of your data and/or your control over the browsers your users use, it may be a viable option. Setting the directive with SameSite=lax will allow "top-level navigations which use a 'safe'...HTTP method."

how to deal with access token and refresh token in client side

I am creating a website using AngularJS client side and communicating in REST with a backend (in an other domain).
To authenticate every calls, I pass a token through the header of each HTTPS call : "Authorization : Bearer access_tokenXXXXXX"
When the token expires, I am able to create a new one thanks to a refresh_token.
The access_token and the refresh_token need to be stored client side, because the browser needs to have it in clear text before setting it in the HTTP request header.
My questions are :
Question 1 : What is the recommanded way to store the access_token and the refresh_token to make it available to the browser so it is relatively secure? (I have quiet sensitive data like personal pictures)
Question 2 : What are the recommanded lifetime (= time before it is not usable) for access_token AND refresh_token? (FYI I refresh the token after a 401 response, and my app is a social app)
Question 3 : Do I have an architactural issue? Should I change it in order not to have JavaScript using token at all, and use HTTP-ONLY cookies?
Thanks :)
Geoffrey
UPDATE :
I finally chosed to go for HTTP-ONLY cookies. I am using Django Oauth Toolkit so Django is waiting the authorization in the HTTP header, and not in a cookie.
To solve that, I am using a Middleware that gather the token of the cookie and set it in the header. It should also allow me to re-authenticate the user (with the refresh token) before the access_token expires.
I think you're right in asking question 3. Definitely use HTTP-Only cookies, that's the safest type of browser storage.
As described in the links provided by smwikipedia, using HTTP-Only cookies helps defend against XSS. To also defend against CSRF you should check out this AngularJS mechanism.
The actual format of the cookies can be JWT or anything else.
The answer to question 2 really depends on your users' sweet spot in trading off between tight security and convenience. You know your users best so it's really your own judgement call.
I am facing similar questions to yours.
I am developing a service layer for both browser-based and non-browser clients. I plan to use JWT (JSON Web Token) to authenticate both.
It's too long for a comment so I post it as an answer.
For question 1, according to here, they recommend to store JWT token in cookie due to security considerations.
For question 2, here is a thread about expiration handling for JWT.
For question 3, I have no comment yet.

How often does the CSRF token change in YII frame work

I have recently read about csrf tokens. I am using YII framework to develop my project. I enabled csrf validation in config/main.php and yii is putting a token in a hidden form field. And checking if the token is valid. Everything is fine. But I have observed that the value of CSRF token is not changing when I refresh and all the forms in a page are using same token.
This puzzled me. If csrf token is not changing then any hacker can use that token in his request also and will be able to produce a valid request. Then how can csrf token offer security? Is it a problem with YII framework? Or did I miss some thing? I hope I did miss something. If we have to generate tokens manually please let me know how to generate and validate(preferably in YII framework)
implement Csrf token generation per session.
check
how the hacker will get token generated to your session?
there is also a procedure for per request token generation, but i think that is not good approach in yii.
problem with per request token generation

Resources