What if JWT is stolen?

What if JWT is stolen?

I am trying to implement stateless authentication with JWT for my RESTful APIs.

AFAIK, JWT is basically an encrypted string passed as HTTP headers during a REST call.

But what if there's an eavesdropper窃听者 who see the request and steals the token? Then he will be able to fake request with my identity?

Actually, this concern applies to all token-based authentication.

How to prevent that? A secure channel like HTTPS?

Can this also help? - "A common security mechanism for detecting token theft is to keep track of request IP address origins." - described in detail in last section here - firebase.google.com/docs/auth/admin/manage-sessions
– Ula
Aug 29 '18 at 4:51
 
According to here (stormpath.com/blog/…), seems HTTPS is necessary. Dec 14 '15 at 6:12
 
 
回答1

I'm the author of a node library that handles authentication in quite some depth, express-stormpath, so I'll chime in with some information here.

First off, JWTs are typically NOT encrypted. While there is a way to encrypt JWTs (see: JWEs), this is not very common in practice for many reasons.

Next up, any form of authentication (using JWTs or not), is subject to MitM attacks (man-in-the-middle) attacks. These attacks happen when an attacker can VIEW YOUR NETWORK traffic as you make requests over the internet. This is what your ISP can see, the NSA, etc.

This is what SSL helps prevent against: by encrypting your NETWORK traffic from your computer -> some server when authenticating, a third party who is monitoring your network traffic can NOT see your tokens, passwords, or anything like that unless they're somehow able to get a copy of the server's private SSL key (unlikely). This is the reason SSL is MANDATORY for all forms of authentication.

Let's say, however, that someone is able to exploit your SSL and is able to view your token: the answer to your question is that YES, the attacker will be able to use that token to impersonate you and make requests to your server.

Now, this is where protocols come in.

JWTs are just one standard for an authentication token. They can be used for pretty much anything. The reason JWTs are sort of cool is that you can embed extra information in them, and you can validate that nobody has messed with it (signing).

HOWEVER, JWTs themselves have nothing to do with 'security'. For all intents and purposes, JWTs are more or less the same thing as API keys: just random strings that you use to authenticate against some server somewhere.

What makes your question more interesting is the protocol being used (most likely OAuth2).

The way OAuth2 works is that it was designed to give clients TEMPORARY tokens (like JWTs!) for authentication for a SHORT PERIOD OF TIME ONLY!

The idea is that if your token gets stolen, the attacker can only use it for a short period of time.

With OAuth2, you have to re-authenticate yourself with the server every so often by supplying your username/password OR API credentials and then getting a token back in exchange.

Because this process happens every now and then, your tokens will frequently change, making it harder for attackers to constantly impersonate you without going through great trouble.

Hopefully this helps ^^

回答2

I know this is an old question but I think I can drop my $0.50 here, probably someone can improve or provide an argument to totally decline my approach. I'm using JWTs in a RESTful API over HTTPS (ofc).

For this to work, you should always issue short-lived tokens (depends on most cases, in my app I'm actually setting the exp claim to 30 minutes, and ttl to 3 days, so you can refresh this token as long as its ttl is still valid and the token has not been blacklisted)

For the authentication service, in order to invalidate tokens, I like to use an in-memory cache layer (redis in my case) as a JWT blacklist/ban-list in front, depending on some criterias: (I know it breaks the RESTful philosophy, but the stored documents are really short-lived, as I blacklist for their remaining time-to-live -ttl claim-)

Note: blacklisted tokens can't be automatically refreshed

  • If user.password or user.email has been updated (requires password confirmation), auth service returns a refreshed token and invalidates (blacklist) previous one(s), so if your client detects that user's identity has been compromised somehow, you can ask that user to change its password. If you don't want to use the blacklist for it, you can (but I don't encourage you to) validate the iat (issued at) claim against user.updated_at field (if jwt.iat < user.updated_at then JWT is not valid).
  • User deliberately logged out.

Finally you validate the token normally as everybody does.

Note 2: instead of using the token itself (which is really long) as the cache's key, I suggest generating and using a UUID token for the jti claim. Which is good and I think (not sure since it just came up in my mind) you can use this same UUID as the CSRF token as well, by returning a secure / non-http-only cookie with it and properly implementing the X-XSRF-TOKEN header using js. This way you avoid the computing work of creating yet another token for CSRF checks.

 
 
 
原文地址:https://www.cnblogs.com/chucklu/p/15683188.html