Java – how to correctly use JTI to declare JWT to prevent replay attacks?
I created some rest APIs using spring and implemented spring security using JWT for authentication My front end runs angularjs and uses these other APIs to receive JSON responses JWT Authentication works normally, but it allows simple copying and pasting of request parameters and headers from the browser console to postman or any other rest client in order to obtain a successful response from the protected API on the back end
I try to solve this problem by using JTI declarations in JWT I plan to use different JTI values for each post - request validation, so just stealing headers from the browser won't work
Now, after a lot of available online resources, I still don't know whether the client or server should set the JTI value in JWT
According to my understanding, if I do this on the server side, I will have to send a new JWT and each response, and expect to keep the record of jtis used in the database in the next request of the client But if the attacker finds out, they just need to use the token in the previous request, and then they can easily interact with my API
On the other hand, if I do this on the client side, I will have to keep the JWT's Secret signature key and JTI generation logic in the JavaScript code so that it can attach the JTI value and hash the token again My question is:
>What is the correct way to achieve this? Did I miss anything or go completely in the wrong direction? > Can I implement any other solution to disable or de authenticate any requests from non browser clients (the way that happens in traditional spring MVC applications using JSPS)?
Any help would be appreciated It's been going on for a long time now
Solution
I can't talk to Java / spring, but I can try to clarify your concerns about JWT and JTI declarations
Implementing JTI to uniquely identify JWT can help prevent an attacker from sending replay attacks that request the same JWT The server will generate the JTI value and send it with the new JWT on each response When a new request is received, the server must verify the JTI value (to ensure that it has not been used before) This does require some kind of persistent storage on the server, which looks more or less similar to traditional sessions, so it feels a little strange, because one of the advertising benefits of JWT is "stateless applications"
Your concern about man in the middle attack is completely correct: if someone intercepts JWT (and its one-time JTI) and makes a request before you do it, their request will be considered valid, and your subsequent requests will be displayed as "replay" on the server (and the server will think they are invalid)