I have created some REST APIs using Spring and implemented Spring Security with JWT for authentication. My front end runs AngularJs and consumes these rest APIs receiving JSON responses. The JWT authentication works fine but it allows for simple copying and pasting of request parameters and headers from the browser's console into Postman or any other REST client to fetch successful responses even from protected APIs from the back end.
I am trying to solve this problem by using JTI claims within the JWT. I plan to use distinct JTI value for each request post authentication so that simply stealing headers from browser wouldn't work.
Now after going through plenty of resources available online, it is still not clear to me whether the client or the server is supposed to set the JTI value in the JWT.
As per my understanding, if i do this on the server side, i will have to send a new JWT with every response and expect it in the next request from the client while maintaining a record of used JTIs in a database. But if an attacker figures this out they'll just have to use a token from a previous request and they can comfortably interact with my APIs thereafter.
On the other hand if i do this on the client side, i'll have to keep the secret signing key of the JWT and the logic for JTI generation in the javascript code so that it may append a JTI value and hash the token again. My questions then are:
Any help is highly appreciated. Been stuck on this for a long time now.
The JWT spec provides the jti field as a way to prevent replay attacks.
A jti is an optional claim." The JWT jti (JWT ID) claim is usually used to prevent replay attacks by preventing the same JWT from being replayed. And the “exp” (Expiration Time) Claim is used to determine how long a JWT is valid.
The jti-claim command specifies whether to add a JWT ID ( jti ) claim to the JWT during API processing. When enabled, a UUID is generated and set as the value of the JWT ID claim.
jti = randomNumber1 + "-" + randomText + "-" + (new Date().
I can't speak to Java/Spring, but I can try to clarify your concerns regarding JWTs and JTI claims.
Implementing a JTI to uniquely identify a JWT can help prevent replay attacks where an attacker sends the same JWT to make a request. The server would generate the JTI value and send it along with a new JWT on every response. When receiving a new request, the server would have to validate the JTI value (to ensure that it had not been used before). Implementing this does require some sort of persistent storage on the server, which can look more or less like traditional sessions, so it feels a bit weird since one of the advertised benefits of JWT is a "stateless application".
You're absolutely correct about your concern of a man-in-the-middle attack: if someone DOES intercept the JWT (and its single-use JTI) and then makes a request BEFORE you do, their request will be considered valid and YOUR subsequent requests will appear to the server to be "replays" (and the server would consider them invalid).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With