dwyl / learn-json-web-tokens

:closed_lock_with_key: Learn how to use JSON Web Token (JWT) to secure your next Web App! (Tutorial/Example with Tests!!)
MIT License
4.18k stars 254 forks source link

Why the "single use" could solve MITM? #68

Closed NE-SmallTown closed 7 years ago

NE-SmallTown commented 7 years ago

The section about MITM(Man-in-the-MiddleAttack) says that "use one-time-use (single use) tokens (which expire after the link has been clicked)" is a solution of MITM.

My question is that if the token just use once,it will cause that the user must login again after every time the request be send.On the other hand,if the server destroy the token and return the new token every time,the new token still could be intercepted by the middleman.

If I am wrong,please let me know,thanks!

nelsonic commented 7 years ago

@NE-SmallTown good question. Using single-use tokens is good practice for application security. If you want to use this pattern you can setup an onPreResponse hook that automatically updates the JWT for each response.

the question you have to answer is: how are you planning on ensuring that a token is not re-used? you would need to store the identifier in some sort of database (we typically use redis for this in our apps) and check if the token has already been used.

NE-SmallTown commented 7 years ago

@nelsonic Thanks for your reply.I am a little confused.

There is a question.

As you say,the process is:

user access the home page and send the token in the header(assuming they have logined)

                                       |
                                       |
                                       ↓

server receive the token and then get the userId by decoding the token,and then go to the database(assuming I use database rather than redis) to take the corresponding token of the userId,and then check whether they are equal by using == operator.If it is,then destroy the token and generate a new token and push it to the database and response it and the data to the client.

There is a question,we just use == operator to check,but we know that the token itself has the vertify mechanism,we don't use it?e.g:

JWT.require(Algorithm.RSA256((RSAKey) publicKey))
                .withIssuer("auth")
                .withSubject("ne-smalltown")
                .withAudience(userId)
                .withArrayClaim("jwt-role", userRole)
                .build()

If I am wrong,could you tell me how and where to use the token itself vertify mechanism like above?

IMO, the only place I can use the token itself vertify mechanism is where I get the old token's exp parameter and put it to the new token so that I can check whether the token is out of date to make user relogin.

                                        |
                                        |
                                        ↓

The client receive the new token and push it to the localstorage to replace the old token.And in the next request,it will use it.

NE-SmallTown commented 7 years ago

@nelsonic Hello?

nelsonic commented 7 years ago

@NE-SmallTown my apologies for not replying immediately. The JWT specification does not have a claim/mechanism for single-use invalidation see: http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#RegisteredClaimName

@jbspeakr has a post on how to single-use JWTs, see: https://www.jbspeakr.cc/howto-single-use-jwt/

NE-SmallTown commented 7 years ago

@nelsonic Thanks for you share the post.

The post says:

In theory, this also works with use-cases besides password-reset tokens e.g. email activation, account confirmation

I agree that these cases suit for single-use-jwt,but my case is the jwt include the user role information and the role is constant,it doesn't like the password-reset,email activation,account confirmation,etc.

So,back to the question,in my case,now I think there is unnecessary to vertify the token,just use == operator with the database's token.