I have began building an application using React JS and Laravel 5.5. I have installed the Laravel Passport and have successfully managed to log my user in and out in my React JS app - but I have been told to look into using httponly cookies for security purposes.
In my working code, I have simply stored the access token in localStorage and sent it to the api using Authorization': 'Bearer ' + token in the axios headers, and this works perfectly. However, when I set a cookie using httponly I can't fetch the value of it (which I assume is exactly the point!) - using react-cookie (from npm), if I log cookie.loadAll() to the console then the only cookie I see is a new XSRF-TOKEN cookie, but not the accessToken cookie I set. So how do I go about sending this token to the api?
Since you can't read the httpOnly cookie from JS, when getting a new token from the backend, the backend has to send the token in the response body.
Browser session cookie usage and bearer tokens are different strategies of authentication (cookie based and token based).
In my opinion they should not be mixed.
Lavavel passport supports authentication with bearer token or with cookie out of the box (see condition at TokenGuard user)
You have to use Passport::cookie for this.
In this case you will be able to set cookie and use HttpOnly flag with other attributes to secure them.
Httponly cookie as bearer token doesn't make much sense. Having cookies httponly helps to protect you and the user against XSS attack as their not readable by javascript. They can be used e.g. for storing session information and are sent when the user do e.g. a page reload.
Setting Authorization header to 'Bearer ' + token is correct way how to sent token to the api. Before using token on the api server you should always check if the token is still valid.
Related
Laravel documentation says:
Laravel automatically generates a CSRF "token" for each active user session managed by the application. This token is used to verify that the authenticated user is the person actually making the requests to the application. Since this token is stored in the user's session and changes each time the session is regenerated, a malicious application is unable to access it.
Laravel config session.php file guarantees session cookie lifetime is 120 minutes by default:
'lifetime' => env('SESSION_LIFETIME', 120)
So let's imagine, for example, I authenticate into the Laravel app and receive session cookies. What will happen if within 120 minutes after authentication I will go to a malicious website and get exposed to CSRF attack? Of course, considering the fact cors.php config is set to allow accept any (*) origin ('allowed_origins' => ['*']).
In my current understanding within these 120 minutes after authentication browser has the session cookie, so if I go to a malicious website and get exposed to CSRF attack, the attack will be successful.
Please correct me if my current understanding is wrong?
So the problem with my understanding was that I was not aware of the fact you can't access a cookie of the origin that differs from website you are trying to access it. So in case of csrf, origin of malicious website differs from the origin of CSRF-TOKEN cookie which is provided by Laravel server, therefore attacks fails. So yeah laravel csrf protection works.
Full explanation of CSRF protection to the beginners as myself:
What is csrf attack?
Imagine, you authenticated into website with domain A, and received the session cookie from server that serves the site A. Annother malicious website with domain B contains a script which produce a request to the server which serves domain A as you enter the site B. As long your browser contains the session cookie of website A, the script attempting to attack from website B will be successful.
So how does csrf token help to cover this vulnerability?
Now laravel server sends you response with XSRF-TOKEN cookie, when you try to send axios request with script from domain A, axios automatically places value of XSRF-TOKEN to X-XSRF-TOKEN header in case of same-origin request (when website A has domain of the same origin as the server). In case of malicious website with non same-origin request, script can't access the XSRF-TOKEN cookie because it is not possible to accesss a cookie of another origin. So axios can't place a value of XSRF-TOKEN to a requst header or a request parameter. Server examines incoming request for X-XSRF-TOKEN or csrf token parameter, server is not able to find it, and so therefore server doesn't validate the request.
I have a webapp that has a javascript page that makes ajax calls up to the webservices. The authorization scheme used for the site is JWT with bearer tokens being used in the authorization header.
However, I now realize that I am vulnerable to XSS, because the token is being stored in a cookie, and the javascript needs access to this in order to set the bearer token in it's requests. Because of this, httponly is set to false, thus meaning my token can be stolen.
So, what I would like to know is whether there is a way to protect against both CSRF and XSS whilst using ajax requests and JWTs?
Pardon me If I am wrong.
I am going to build a system by using Angular and Laravel API and these are some things about what I am doing.
I am using Passport and I am successfully able to do authentication.
I also want to do a CSRF verification because still I don't know where to store the token. If I store on cookies its vulnerable for CSRF (Thats why need to do a CSRF). What if I store bearer token on local storage ? Should I need to do a CSRF verfify ?.
How can I do a CSRF verify along with bearer token? (using web middleware)
I'm creating a React Js website with a Node.js backend. I've been attempting to figure out a user authentication implementation to prevent CSRF attacks however I'm really confused about where to store Anti-CSRF tokens.
My thought process of a secure implementation is as follows...
User submits request to login with credentials.
Credentials are authenticated.
Server creates session.
Server creates JWT to use as Anti-CSRF token.
Server stores JWT (Anti-CSRF token) in session storage.
Server sends response to client.
Response has header to store session ID in HttpOnly cookie on client-side.
Response payload includes JWT (Anti-CSRF token).
Client receives response.
HttpOnly cookie holding session ID is stored on client-side.
Client stores JWT (Anti-CSRF token) in localStorage.
I figure when a user needs to request information, the client can send the JWT (Anti-CSRF token) via a header or payload, and the session ID will be sent automatically due to it being a cookie. Then, the server can check if the JWT (Anti-CSRF token) exists in the session storage.
I know that the JWT (Anti-CSRF token) will need to be refreshed at some point.
My confusion is due to storing the JWT (Anti-CSRF token) on the client side. I keep reading that it should only be stored on the server. But if it's only stored on the server it doesn't seem to be doing anything at all.
I thought of using both cookies and localStorage because it seems that if a request to the server needs both a HttpOnly cookie and something from localStorage to send back an "authorized" response, an attacker would need to both successfully ride a session and successfully implement an XSS attack to get the Anti-CSRF token.
I just started learning about CSRF and XSS recently so I could be completely wrong and there could be a huge flaw in my implementation that I'm missing. But my main question is... don't Anti-CSRF tokens need to be stored on the client AND the server?
They are also called "CSRF Tokens". When a client requests for a form (e.g. bank login page), server generates the tokens and passes them to client and when the client fills the form, client passes CSRF token along with the completed form. Server verifies the token value and if it matches, request is fulfilled. CSRF tokens are stored on server-side in synchronizer token pattern.
I get JWT token from other api and then want to send it ti my node.js backend and write it in httpOnly cookie.
How to add some data(JWT token) to HttpOnly cookie with koa-generic-session?
koa uses the cookies module where options are simply passed.
docs https://github.com/pillarjs/cookies