jpadilla / django-rest-framework-jwt

JSON Web Token Authentication support for Django REST Framework
http://jpadilla.github.io/django-rest-framework-jwt/
MIT License
3.19k stars 650 forks source link

Security vulnerability that allows hijacking another user's account #417

Open Gnorizo opened 6 years ago

Gnorizo commented 6 years ago

Django REST Framework JWT are vulnerable to a username hijacking attack, in which one user can gain access to another user's account. This occurs because the JWT token identifies the user's account using it's username (which could change) rather than User.pk (the user record's primary key, which is reliable and always points to the same user account. Here's one example (out of many) on how this exploit could be performed:

Step 1: I create account with username "X", create a JWT token, then rename my account to "Y". Step 2: Someone else creates account with username "X". Step 3: I access the other person's account using my JWT token.

Setting a short expiration window into the JWT token doesn't eliminate this threat vector, because a malicious user could design an attack that performs step 1 shortly before step 2 occurs.

The fix is to have the JWT token identify the user account being authenticated using a value that is immutable, such as the pk of the User record (which is id by default, but could be implemented as a uuid). Usernames are a bad choice for long-term identification of users because it's common for websites to allow users to change their usernames.

Alex3917 commented 6 years ago

This library comes with the ability to have a per-user UUID to use as a secret, which you can just rotate when a user changes their username. The basic concept here was reported a while ago, but it should probably be added to the documentation.