We have a token based OAuth authentication mechanism for our angularjs application. The acunetix tool indicated that XSRF threat is there.
Is CSRF an issue for token based authentication (Because we are not using any cookies for user identification / authentication / sessions)?
If CSRF is an issue for token based authentication, is there be any way to implement prevention without using cookies?
As far as I know token based authentication is in no way affected by CSRF. E.g. if you use cookies, and bad guys lure users into their site where they can create a special button that will do a post to your site -> here is CSRF where you can execute some requests on behalf of the users.
Now if you use tokens that are stored in session/local storage e.g., they are never automatically passed with the request. You probably use something like angular interceptor or similar technology to pass it along with every XHR request. This never happens automatically.
You can read a bit more on token auth in this very good post. In point number 6 there is a little section about XSRF/CSRF, XSS.
In my modest experience these big security tools can often tell you something that is not true just to make themselves more "significant". But it would be interesting to know exactly how it plans to execute CSRF and what exactly made it think it is possible? E.g. you might have a cookie that you missed?
P.S.
XSS attack (to steal token) gets more possible with tokens, since you can put HTTP-only like for cookies. So any successful XSS will be able to read your token, so you need to make sure that you have a good protection against that. But it's usually covered well by frameworks.
Related
I've spent a few days trying to figure out a secure authentication method for SPA/React (client-side).
Most of the tutorials I've read in the wild contradict each other.
One says have to store in Cookies another in Local Storage, one says don't need to use refresh token, one says have to use a refresh token.
I'm building a React SPA app for the frontend and Express for the API (backend). Both are stored in the same domain:
React: example.com
Express: api.example.com or example.com/api
Is it enough to secure my application by using Cookie (access token JWT):
httpOnly:✅
secure: ✅
sameSite: strict
without refresh token
This matches the answer here: https://stackoverflow.com/a/57779076/11340631
The question is:
Is this safe enough?
How long does it take to set the expiration of the access token?
Is this as per Oauth recommendation?: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps
What if my access token is stolen? For example, my friend is using my PC and he stole my cookies and use it in his PC browser.
I really hope to get the answer here, any answer is appreciated.
It's safe against extracting the token with Cross Site-Scripting, but, without other security controls it might be prone to Cross Site Request Forgery (cookies are automatically attached to a request). Is API accepting key in the cookie or must it be sent in the Authorization Bearer header?
My concern is, that if you're not using refresh token, the access token must have a relative long expiration. OAuth2 was not intended to be used to authentication alone, but together with some session-like solution, for example OpenID Connect and SSO.
The shorter the better, unless it can be revoked any time server-side. If there's no way to revoke the key, the 5 minutes expiration date is, in my opinion maximum. That's why refresh token and session-like endpoint is the must.
OAuth is not designed for web application client's authentication at all. That's the common anti-pattern in many projects I've pentested. https://oauth.net/articles/authentication/
I'm glad for your awareness of such a threat. Access tokens must either live very shortly, or they must be revoked server-side in a some way, for example by utilizing some kind of revoke-list. Or the refresh token with server-side-like session endpoint should be utilized.
I've built an API with Node.js/Express which I'm currently using alongside my Angular app.
For authentication, I have a username/password setup which then returns a JWT which is happily used.
Now, I've been spending some time (and reading such Stormpath articles) I want to use cookies rather than localstorage for storing these JWTs. And thats where my questions begin.
So what I've essentially done thus far is updated the saving and reading, e.g. for saving from $window.localStorage['jwtToken'] = token; to $cookies.put('jwtToken', token);. And for reading, from return $window.localStorage['jwtToken']; to return $cookies.get('jwtToken');
At this stage I was wondering whether someone could help me understand a few bits, kindly correct and inform me of any missing parts of knowledge:
1 - So in addition to the actual saving and reading as above, is there anything else I need to explicitly set - what I think is HttpOnly cookie flag (so JS can't access the cookie data.
1b - Do i also need to update my node API so that instead of returning res.json its doing res.cookie?
2 - Do i also need to set the Secure cookie flag so that its sent via HTTPs. So at present i wrote a simple authInterceptor that attaches a header with each request: config.headers['x-access-token'] = token;. Is this where that secure cookie flag would be set?
3 - So using cookies am i correct to understand XSS attacks are minimised as JS can't touch the cookies however I need to concentrate on CSRF. For this I am thinking of using this CSRF middleware on my node api server side and use this alongside Angulars built in XSRF-TOKEN as described here. Is this a good implementation to follow?
4 - When looking at Chrome inspector, I see the cookie containing the JWT, however the HTTP/Secure/Same-Site are all untucked, also the Expires says Session. Could someone please explain what this means:
Sigh, I think thats it, sorry if its a little long winded. Hopefully others can gain from what we learn here.
Any help appreciated.
Thanks.
If you set HttpOnly $cookies.get('jwtToken'); wouldn't work...
1b. Don't understand the question here...
The Secure flag tells the browser to only include the cookie if the request is an HTTPS request. You can still make HTTP requests, but the cookie will not be included. document.cookie = "name=somevalue;secure"
If you set HttpOnly so that JavaScript can't read the cookie, that's some protection, but if you have XSS, then all bets are off. The injected script could still perform network requests, and do exactly what your code is doing to include the CSRF tokens. You still need CSRF-protection, but in most cases XSS means circumvention of CSRF-protection.
Session means the cookie will be deleted automatically if you close the browser (which people don't really do all that often anymore).
I am using laravel 5 and angular js and JWT authentication for logging and registering my users. But there is nothing mentioned about to facilitate users with remember me functionality and also allow users to reset password when forgotten password.
I researched a lot and didn't find exactly what I need though the answer in following link is helpful but inadequate for me to proceed.
Laravel 5 Password Reset with Angular View
Kindly provide any information and links that would be helpful.
Thanks in advance! :)
To Answer from a JWT perspective.
Remember me is essentially asking the user how long they want to login for. Depending on the security requirements and typical usage patterns of your users, short sessions are often from 15 minutes and up to a browser session. Long sessions (selecting Remember me) can be anything from 24hours to a year.
The JWT issuer can set the exp claim (expiration time of the token) differently depending on the user's selection of the 'Remember Me' checkbox.
If you're intending the 'Remember Me' to last longer than a single browser session, the simplest way is to store the token in a cookie. This means the cookie also needs to have the following properties set: httponly, secure, and expires (with the same expiry time as the exp claim from the token).
Rest Password implementations come in many shapes and sizes depending on your requirements. These are not directly related to JWTs as they come before the JWT issuer will issue a token.
You're asking for something that will need to be handled specifically for your case. The way most "remember me" systems work (including Laravel) is via storing a cookie on the user's device. That cookie is then used to authenticate automatically when the user returns. JWT is different as you are given a token, rather than a cookie, that you pass back to the server in a header. They are both essentially strings of letters and numbers, but you'll specifically have to store the JWT token on the user's browser in order for a "remember me" type of functionality. You might do this in the Angular app using localStorage or some other similar front-end practice.
For the forgotten password, you can submit the same form fields that are default to Laravel and simply override how the PasswordController returns the response; in this case needing a JSON response rather than a redirect.
I need some advice regarding using session tokens to authenticate users. I am building an AngularJS app which uses an API to tie in with the backend. I am only building the front end, not the backend. The documentation states that all calls to the API have a session token attached in the body of the request (POST).
I would like to know about the security of storing this token in localStorage. That is where I am storing it now and retrieving and attaching it to each API request. After login, the server sends the session token in the body and I save it from there.
There is no documentation about an x-access-token header that should be sent with the request made to the server. It is not being checked server side. What are the implications of this? I feel that it is susceptible to attacks without this added layer of security.
My main concern is the security of this setup. I want to know what the best setup is to make sure this app is as secure as possible and recommend changes to the way the backend is setup to facilitate this.
Thanks!
As you tell, you are only working on the UI part and not the backend. It is up to the backend team to ensure headers are properly evaluated and security is enforced (btw request headers do not belong to request body). Just put the token into the x-access-token header as they tell.
Storing the token inside the localStorage gives you a little more control over the cookie: You will not accidentally send it to unnecessary URLs. However, older browsers do not support it - you may need to use a shim for that.
In a case of SPA, you may consider not storing the token at all: It could be fetched each time your application is accessed and then stored within a service in angularjs, but it depends how your fetch/login operation is implemented (is it always interactive, how long does it take, etc).
I would suggest use $cookies rather than localstorage. As localstorage does not support some legacy browser.
I am using cookies to store token in my project
It is common to authenticate to web services using an authorization header which contains a secret token. And since the security of this mechanism depends on the token to be secret care should be taken that this token is not leaked.
There are countless tutorials on the web which explains how such an authorization header can be set using angular and least the ones that I have actually read use an $http interceptor and now one discusses that the token is not leaked.
There are some public and some private APIs out there which can be talked to cross domain thanks to CORS. And obviously I do not want to send my internal authorization tokens on any of those requests.
Some other techniques come to mind such as setting the token manually only on each and every request, but that means lots of duplicate code. The $http server could be wrapped in an $authenticatedHttp service so that it is always appearent from the object used whether it is the authenticated service or the normal one. However the $http service has so many methods to be wrapped.
Is there a better solution?
UPDATE
From the answers I have the impression that my question was not understood. I try it with a more concrete example:
I have a private web page. People have to login with username/password and let's say for simplicity's sake that we use HTTP basic auth, so username/password are bas64 encoded and are transmitted on every request in the HTTP header "Authorization". So far there is no problem.
But there is this great&free weather widget. I can retrieve the current weather information in JSON format from https://myWhateverWeatherService.tld/weather.json. After the login to my private web service I also retrieve the weather information (CORS allows me to do this).
The problem is that even though myWhateverWeatherService.tld does not require any authentication at all, angular's $http service will still append the Authorization header. And I don't trust the guys at myWhateverWeatherService.tld. Maybe they just set up the service so they can steal Authorization token and do lot's of nasty stuff with them.
I need some reliable way to deal with that. I already thought about checking the url with some regex in the interceptor. This is possible, but it is also not to difficult to forget about a certain case that my regex will miss.
The token is always sent through the wire, I guess that is the most vulnerable part of it.
Since the token must always be present on the http header itself, the only way to make the request more secure is to encrypt the whole request, and for that you should use SSL.
If you are concerned about the safety of storing the token on the client machine, you can keep it only on the browser´s memory, without persisting it on a localstorage or something like that. So every time the user closes the browser and open it again, s/he must log in.