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

Discuss: Security concerns #30

Open
lmammino opened this issue Jul 6, 2017 · 7 comments
Open

Discuss: Security concerns #30

lmammino opened this issue Jul 6, 2017 · 7 comments

Comments

@lmammino
Copy link

lmammino commented Jul 6, 2017

I think it's unsafe to leave sensitive data such as access tokens (in the case of Oauth2 like Google).

If an attacker is able to retrieve a cookie he can easily decode the JWT token and use the access token to issue arbitrary requests to the authentication provider APIs and retrieve any information that might have been originally granted to it by the user (e.g. read my Gmail emails...).

I think the point of this lib is to make this kind of authentication processes stateless (or backendless) and storing the access tokens directly in the cookie is an easy win. Anyway I would at least try to protect this sensitive data by applying some level of encryption, maybe a simple symmetric encryption, using the same secret used to generate the JWT token signature as key would enough...

I look forward to knowing the community thoughts on this matter

@lipp
Copy link
Owner

lipp commented Jul 7, 2017

Thanks for your feedback! I always like to make this project more secure, so every discussion around this is very welcomed.

These are the security aspects:

  • The cookie is only shared between subdomains (x.foo.com, b.foo.com, www.foo.com, foo.com)
  • The cookie is https only -> no eves dropping / reading traffic
  • The cookie (JWT) is encrypted
  • The cookie (JWT) is http-only (not readable via script attack)

IMHO this is pretty secure. If the attacker still gets the cookie and can decrypt it:

  • why should he/she stop there?
  • how much more security do you get when encrypting the API keys?

I am very interested what other folks have to say!

@lipp lipp changed the title Encrypt sensitive data (e.g. access tokens) Discuss: Security concerns Aug 2, 2017
@danthareja
Copy link

@lipp, thanks for your work on this project! I have a (potentially naive) question about JWT encryption and thought it might be an appropriate part of this discussion.

My understanding when you say the cookie (JWT) is encrypted is that without a decryption key, it is not possible to read the contents of the cookie. However, I am able to access the contents by Base64 decoding the middle part of the JWT.

Reproduction steps

My JWT (stored in the cookie) according to login-with
screen shot 2017-08-22 at 1 47 50 pm
My payload (access token has been revoked) according to login-with
screen shot 2017-08-22 at 1 47 55 pm

If I copy the whole JWT into jwt.io's debugger, I immediately see my access token available in the payload section:

screen shot 2017-08-22 at 1 53 02 pm

Additionally, if I just copy the middle part of the JWT (the payload), I get the same result.
screen shot 2017-08-22 at 1 53 39 pm

My question

Assuming someone gets my JWT from the cookie, is there anything to stop them from using my access token to access the GitHub API? Is there a misunderstanding on my part between encoding and encryption?

Thanks for your help :)

@lipp
Copy link
Owner

lipp commented Aug 23, 2017

@danthareja THX for investigating. This might be serious. I'll look into this ...

@lipp
Copy link
Owner

lipp commented Aug 23, 2017

after thinking about it... this is intentional 😄
The JWT can be read as you described. It is still secure as:

  • Your microservices using that cookie have to validate the signature (LW_JWT_SECRET) and only operate if they are valid.
  • The cookie is bound to your domain (LW_SUBDOMAIN=auth.foo.com -> *.foo.com and foo.com). The browser will never send the cookie to other domains / websites.
  • The cookie is http-only and thus can not be modified by malicious scripts or other attacks.
  • The cookie is "secure" and thus forces you to use https, so nobody can read it (evesdropping)

Hope this makes things clearer.

@danthareja
Copy link

@lipp - thank you, this does indeed clear things up.

@lipp
Copy link
Owner

lipp commented Aug 27, 2017

@danthareja great!

@feluxe
Copy link

feluxe commented Jan 13, 2018

There is a nice strategy to prevent CSRF attacks called Double Submit Cookie. I think it works like this:

login-with adds a random key to the payload of the JWT that it stores in the httponly=true cookie (this one cannot be accessed from the JS client.).

login-with creates another JWT and signs it with the random key from above. This token is stored in another cookie, which is httponly=false (that means it can be access by the JS client).

Now in order to request a secure API endpoint the client JS application has send the token from the httponly=false cookie with the HTTP header.

That means the API receives two tokens for each request, one over the HTTP headers from the JS client and one from the httponly=true cookie.

To validate the user the API decodes the first JWT (the one from the httponly=true cookie) and takes the key from the payload to decode the second JWT (the one from the HTTP header). If both tokens decode the user is valid.

You can find more on this here:

https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet#Double_Submit_Cookie

https://stackoverflow.com/a/37396572/1612318

login-with could provide an env var called CREATE_CSRF_TOKEN=true/false or something. If it's set to flase you just leave the extra cookie and the key in the payload of the httponly=true cookie out.

I think this would be easy to implement (just the first two steps from above). The biggest challenge I see would be the documentation for something like this. ^^

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

4 participants