Search code examples
pythonjwtaccess-tokendjango-rest-auth

JWT authorization and token leaks


I need help understanding the security of JWT tokens used for login functionality. Specifically, how does it prevent an attack from an attacker who can see the user's packets? My understanding is that, encrypted or not, if an attacker gains access to a token, they'll be able to copy the token and use it to login themselves and access a protected resource. I have read that this is why the time-to-live of a token should be short. But how much does that actually help? It doesn't take long to grab a resource. And if the attacker could steal a token once, can't they do it again after the refressh?

Is there no way to verify that a token being sent by a client is being sent from the same client that you sent it to? Or am I missing the point?


Solution

  • how does it prevent an attack from an attacker who can see the user's packets?

    Just because you can see someone's packets doesn't mean that you can see the contents. HTTPS encrypts the traffic so even if someone manages to capture your traffic, they will no be able to extract JWT out of it. Every website that is using authentication should only run through HTTPS. If someone is able to perform man-in-the-middle attack then that is a different story.

    they'll be able to copy the token and use it to login themselves and access a protected resource

    Yes but only as the user they stole the token from. JWT are signed which means that you can't modify their content without breaking the signature which will be detected by the server (at least it is computationally infeasible to find the hash collision such that you could modify the content of the JWT). For highly sensitive access (bank accounts, medical data, enterprise cloud admin accounts...) you will need at least 2-factor authentication.

    And if the attacker could steal a token once, can't they do it again after the refressh?

    Possibly but that depends on how the token has been exposed. If the attacked sits on the unencrypted channel between you and the server then sure they can repeat the same process but this exposure might be a result of a temporary glitch/human mistake which might be soon repaired which will prevent attack to use the token once it expires.

    Is there no way to verify that a token being sent by a client is being sent from the same client that you sent it to?

    If the attacker successfully performs man-in-the-middle attack, they can forge any information that you might use to verify the client so the answer is no, there is no 100% reliable way to verify the client.


    The biggest issue I see with JWTs is not JWTs themselves but the way they are handled by some people (stored in an unencrypted browser local storage, containing PII, no HTTPS, no 2-factor authentication where necessary, etc...)