Security of storing Bearer token in cookies
Asked Answered
P

2

14

My SPA uses React as front end and laravel API as backend.

When the user logs in (via axios and api), the api returns an access (Bearer token) as response. I use the react-cookie framework to store the access token as cookie in the Browser. This cookie will be read and used for any future request.

Is this the right way to do? Isn't cookie data just something in the Browser that can be easily obtained by any attacker? Since it is just a file one the computer somewhere.

What is stopping an attacker from grabbing that cookie, impersonate as that user and start performing actions that requires authentication?

The token has a life span of lets say 1 year. It will only be refreshed every time the user logs in. I understand that if I set the life span shorter it will be more secure. However that will mean the user would have to log in constantly?

-----Update-----

Im not sure if any of the provided solution answered my question. A SPA app is front end based and the request can be from anywhere such as Postman, Mobile app, or any third party device that wish to talk to my backed server. So those device needs a way to store some access token locally to be used for any future request.

The only way I know this could happen is for my server to send some auth token to the requester and have it store it somewhere to be used for next request.

In this case, Im not sure if CSRF token or any other means would help my concern?

Just like facebook, if I clear my cache, I will have to re-login. That means facebook is storing something on my location computer so I can be automatically authenticated next time

Pires answered 30/9, 2018 at 2:27 Comment(0)
M
9

Your JS should not have access to the cookie. There are flags you can set on cookies that will help protect them and make sure they are only used for the correct purposes.

The HttpOnly flag is set on the cookie then JS will not be able to access it but it will still be sent with any request.

The SameSite flag will ensure that the cookie is only sent back to the site that gave it to you. Which prevents leakage.

The Secure flag will make it only send the cookie over a secured connection to prevent someone from sniffing it out of your web traffic.

Edit

You might want to lookup an authorization workflow but the gist of it is this:

  1. User logs in with username and password
  2. A JSON web token is issued upon login from the backend and sent to the browser
  3. The JWT(JSON web token) can be stored in a cookie in the Web Storage(Session Storage) on the browser
  4. Subsequent requests to the REST API will have the token embedded in the header or query string for authorization. With that form of authorization, your REST API understands who is making the request and what kind of resource to return based on the level of authorization

Please see @tpopov answer as he also made some really good points.

Masked answered 18/10, 2018 at 20:5 Comment(1)
I would advise against storing JWTs in localStorage, as it makes them vulnerable to XSS.Shabuoth
P
8

I just want to add some disadvantages of storing tokens in cookies that you should also be aware of:

  • The max size of a cookie is only 4kb so that may be problematic if you have many claims attached to the token.

  • Cookies can be vulnerable to cross-site request forgery (CSRF or XSRF) attacks. Using a web app framework’s CSRF protection makes cookies a secure option for storing a JWT. CSRF can also be partially prevented by checking the HTTP Referer and Origin header. You can also set the SameSite=strict cookie flag to prevent CSRF attacks.

  • Can be difficult to implement if the application requires cross-domain access. Cookies have additional properties (Domain/Path) that can be modified to allow you to specify where the cookie is allowed to be sent.

------- Update -----

You can also use cookies to store the auth token, even it is better (at least in my opinion than using local storage, or some session middleware like Redis). And there are some different ways to control the lifetime of a cookie if we put aside the httpOnly and the secure flags:

  • Cookies can be destroyed after the browser is closed (session cookies).
  • Implement a server-side check (typically done for you by the web framework in use), and you could implement expiration or sliding window expiration.
  • Cookies can be persistent (not destroyed after the browser is closed) with an expiration.
Polder answered 22/10, 2018 at 9:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.