Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Login redirect & token refresh #19

Closed
michaelbromley opened this issue Sep 10, 2018 · 4 comments
Closed

Login redirect & token refresh #19

michaelbromley opened this issue Sep 10, 2018 · 4 comments

Comments

@michaelbromley
Copy link
Member

The JWT generated on login is time-limited. Once it expires, the session is no longer valid and the user must login newly.

For a long, continuous user session, this is undesirable. The token should be refreshed during use. Needs research on how this is best achieved.

Secondly, if user is inactive for an expended period (e.g. puts laptop to sleep, opens next day and admin ui is still open in browser), then the next API call will fail with a 403 error. In this case, the app should automatically re-route to the login page, and upon successful login, redirect the user back to the route they were last requesting before the error.

@michaelbromley
Copy link
Member Author

michaelbromley commented Sep 21, 2018

Related issue: now that the auth operations have been switched from REST calls to GraphQL, errors are no longer being reported correctly.

This seems to be due to the switch from apollo-angular-link-http to apollo-upload-client, which has had the result that the http interceptor no longer gets executed on http calls.

@michaelbromley
Copy link
Member Author

michaelbromley commented Sep 21, 2018

Video guide on implementing a refresh token flow for JWT / express: https://www.youtube.com/watch?v=UA0AIkjI85c

Plus the front-end code used to set and update tokens: https://github.com/benawad/gello-world/blob/7_advanced_jwt_auth/src/index.js

@michaelbromley
Copy link
Member Author

Why use refresh tokens?

While researching this I had the question of "what is the point of refresh tokens?"

From what I read, the auth token should have a short life (say, 5 - 15 mins) whereas the refresh token has a longer life (say, 1 - 2 weeks). User logs in, then the auth token expires after 5 mins and so the refresh token is checked, validated, and a new auth token is issued. The refresh token is presumably stored in the same fashion as the auth token (localStorage, for example). If an attacker can get the auth token, they can also get the refresh token. So where is the additional security?

Answer from https://security.stackexchange.com/a/119392:

Without frequent refreshing, it is very difficult to remove access rights once they've been granted to a token. If you make the lifetime of a token a week, you will likely need to implement another means to handle, for example, the deletion of a user account, changing of a password (or other event requiring relogin), and a change in access permissions for the user.

From reading that whole thread, it seems that the clear purpose of a refresh token is to:

  1. Provide a way of having long-running user sessions while simultaneously
  2. allowing access to be revoked at short notice.

@michaelbromley
Copy link
Member Author

Where to store tokens? localStorage vs sessionStorage vs cookies

https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage

Stormpath recommends that you store your JWT in cookies for web applications, because of the additional security they provide, and the simplicity of protecting against CSRF with modern web frameworks. HTML5 Web Storage is vulnerable to XSS, has a larger attack surface area, and can impact all application users on a successful attack.


From https://www.owasp.org/index.php/HTML5_Security_Cheat_Sheet#Local_Storage

  • Also known as Offline Storage, Web Storage. Underlying storage mechanism may vary from one user agent to the next. In other words, any authentication your application requires can be bypassed by a user with local privileges to the machine on which the data is stored. Therefore, it's recommended not to store any sensitive information in local storage.
  • Use the object sessionStorage instead of localStorage if persistent storage is not needed. sessionStorage object is available only to that window/tab until the window is closed.
  • A single Cross Site Scripting can be used to steal all the data in these objects, so again it's recommended not to store sensitive information in local storage.
  • A single Cross Site Scripting can be used to load malicious data into these objects too, so don't consider objects in these to be trusted.
  • Do not store session identifiers in local storage as the data is always accesible by JavaScript. Cookies can mitigate this risk using the httpOnly flag.

From: https://www.whitehatsec.com/blog/web-storage-security/

Never store sensitive data using Web Storage: Web Storage is not secure storage. It is not “more secure” than cookies because it isn’t transmitted over the wire. It is not encrypted. There is no Secure or HTTP only flag so this is not a place to keep session or other security tokens.

Thoughts

Cookies seem to be the better option but the main issue is CSRF attacks. Angular's HttpClient has built-in CSRF mitigations, see https://angular.io/guide/security#xsrf, so this could be the best way to go. It may also simplify the token transfer/refresh process.

Todo: watch this https://www.youtube.com/watch?v=sHKyMwIK9F0

michaelbromley added a commit that referenced this issue Sep 24, 2018
Closes #16, relates to #19. Still using local/session storage. Next task is to look into using cookies to store tokens. If implemented with CSRF mitigation, it should be more secure and potentially require less work for clients to implement auth.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant