21

We are implementing a REST service that requires authentication and authorization. Because of the stateless nature of REST API's, we want to use JWT to make authenticated calls to the API through a token, without the need to hit a database for each API call.

After evaluating the JWT we had some questions:

  1. How do you handle a situation with a compromised token secret which is shared between a client and the server?
  2. Do you logout all your clients and define a new token secret for future requests? (that would be a bad experience)
  3. Is there a way to just logout the compromised client?

Background detail: We will use that flow between an iOS app and a Node.js backend.

qbi
  • 1,601
  • 2
  • 14
  • 27
BausNauf
  • 311
  • 1
  • 2
  • 3
  • I wanted to share one useful link I found, regarding an idea to revoke granted tokens. http://www.kdelemme.com/2014/05/12/use-redis-to-revoke-tokens-generated-from-jsonwebtoken/ – BausNauf Jul 31 '14 at 00:41

5 Answers5

16

To answer your questions:

1) How do you handle a situation with a compromised token secret which is shared between a client and the server?

Add an expiry date to your token. Make sure the token cannot be used after the expiry time. But this doesn't prevent unauthorized access within the token's expiry period.

So, to overcome this problem you can embed the client's IP address or other such information inside the token. And make sure the incoming request with the token is used from the same IP Address to which it was issued to.

2) Do you logout all your clients and define a new token secret for future requests? (that would be a bad experience)

If you mean logout all clients who are using multiple tokens in a authorized manner, then No. You can continue to use multiple tokens at the same time, provided you have a finite expiry period to the tokens. This make sure your token are used within the intended time window.

But, if you mean when the token is stolen and you somehow figured it out. Its better to invalidate all tokens to that user.

However, you may want to have a mechanism that will revoke all tokens explicitly in special cases. May be like when the user resets his password because he thinks his password may be compromised.

3) Is there a way to just logout the compromised client?

May be, depends on your ability to precisely identify which token has been compromised. Which may lead to all clients using that token to lose access. But, I wouldn't recommend it. But, hey you can always write code that will dynamically re-authenticate and get a new access token when old client can no longer use the token. :-)

Don't be afraid to invalidate a token when necessary. If you loose a token write a dynamic script to re-authenticate. If you think you may loose the session details when you use new token, resend the expired token to server while re-authenticating. Using this expired token you can reconstruct a new token with the old token's session details. Provided you have embedded session details in the expired token.

  • 3
    Adding the IP address and even verifying it won't remove the consequences of the compromised token secret. If the token secret is compromised, a 3rd party can sign forged tokens (which would include a forged IP address or expiration date). The token secret is vital. – Dan Esparza Apr 15 '15 at 17:41
  • 2
    I agree, but everything above I have mentioned is with respect to Token itself. It is assumed that a token secret is never compromised and lives inside the server in a secure way. Its a different challenge on its own. – Hari Krishna Ganji Apr 16 '15 at 06:57
  • 1
    got it. I guess I was just pointing out the OP specifically asked about a "compromised token secret" in question #1. – Dan Esparza Apr 17 '15 at 16:35
  • 1
    Oh! Thanks for pointing it out. I am now confused. :-) However, taking another look at Question #1 ("token secret which is shared between a client and the server"), make me think again. A Token Secret is never shared with the client. I wonder what the author was actually referring to. – Hari Krishna Ganji Apr 27 '15 at 16:11
  • Because the IP address can be spoofed, validating the IP address against the JWT will not always be effective. The attacker may not be able to extract information with a GET request. But if the attacker uses a POST or PUT they may be able to modify the server with the un-expired JWT. – David V Jun 24 '15 at 16:32
  • @DavidV Yeah IP address can be spoofed. But, it can limit the Attack Vector, making it compulsory to have knowledge of the IP address. However IP address is just one way. But you can come up with other information you an embed. Loosing a JWT token is like loosing your house keys. You can send a JWT as a Cookie and mark it HTTPOnly, so that is not easily stolen. Also you can encrypt your entire JWT to keep your IP and other stuff secret and difficult to Spoof. One way to go about would be JWE (https://tools.ietf.org/html/draft-ietf-jose-json-web-encryption-39) – Hari Krishna Ganji Jul 17 '15 at 12:08
7

If you want to be able to revoke previously granted tokens before their expiry date (a valid security concern), you'll need to include a database lookup to that, which negates one of the main advantages of JWT's, so you might decide to not use them in the first place.

Here's an article that talks about this case: https://www.dinochiesa.net/?p=1388

2

In my case I am storing the tokens in my database as well.

enter image description here

During initial authentication, user sends the username password. The credentials are verified and then I generate token which is stored in database as well and send the token to client as well. On every client request, I verify whether the token exist for that user in my database as well.

If the client logs out and wants to revoke the token, I simply remove the token from the identities table.

sonam
  • 121
  • 1
1

JWT tokens can be decoded and all the information can be read as json format, for example:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

The first part is header: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

{
  "alg": "HS256",
  "typ": "JWT"
}

Second part is Payload: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

The last part is the signature that created as:

//In our example, the algorithm is (HS256)
signature = algorithm(hash of (header + payload), secret)

Now, its the key that only hidden inside the signature of the token, then, we get into conclusion that:

  1. The KEY shall be kept in secure place and must not be revealed to anyone.
  2. IF JWT token used for authentication, it must be used over SSL/TLS.
  3. JWT Token shall not be trusted without signature validation with secret key.
  4. ISSUER of JWT token must not put sensitive information inside JWT token in case that only signing of the information used with JWT.

akajas

1) How do you handle a situation with a compromised token secret which is shared between a client and the server?

use SSL/TLS (Secure connection) and expire each token according to your login system. JWT token must be used as permanent, each time user logged in create JWT token.

2) Do you logout all your clients and define a new token secret for future requests? (that would be a bad experience)

IF your secret key compromised, you have to create new secret key definitely and renew active sessions by issuing log-out and force the system re-authenticate all active users.

Akam
  • 1,327
  • 3
  • 14
  • 23
0

How do you handle a situation with a compromised token secret which is shared between a client and the server?

First you need to think about how it is possible:

  1. Are you not on a secure network that attacker can sniff out JWT.
  2. Is you site XSS vulnerable that attacker can run a script an get the token out.
  3. Even if attacker gets you JWT (which is valid for session ids also) how long an attacker has to do the harm? Are you not expiring tokens at regular intervals and generate new ones?

Do you logout all your clients and define a new token secret for future requests? (that would be a bad experience)

Is there a way to just logout the compromised client?

You can blacklist the device token and generate a new token for future requests with that token without affecting clients.

quintin
  • 101
  • 2