Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Potentially IDOR vulnerability in JWTAuthentication class #829

Open
emaces96 opened this issue Oct 23, 2024 · 2 comments
Open

Potentially IDOR vulnerability in JWTAuthentication class #829

emaces96 opened this issue Oct 23, 2024 · 2 comments

Comments

@emaces96
Copy link

Hello I think I found a new security issue in the JWTAuthentication class, I would like to discuss it here and see if my theory is valid before submit it.

The JWTAuthentication class contains a critical Insecure Direct Object Reference (IDOR) vulnerability. The get_user method retrieves a user object based solely on the USER_ID_CLAIM from the validated token, without performing any additional authorization checks.
This design assumes that possession of a valid token implies authorization for all actions related to the user_id in that token, which is a flawed security model. The vulnerability is further exacerbated by the JWTStatelessUserAuthentication class, which creates a
TokenUser object directly from token claims without any database lookup or further authorization checks.

The default_user_authentication_rule function only verifies if the user exists and is active, not considering user permissions or roles. While the CHECK_REVOKE_TOKEN feature provides some mitigation by checking if the user's password has changed, it doesn't prevent the core IDOR issue. An attacker could exploit this vulnerability by obtaining a valid JWT for their
account, modifying the USER_ID_CLAIM to target another user's id, and making API requests.
The server would authenticate the request based on the valid token signature and retrieve data for the specified user id, regardless of whether the
authenticated user should have access to that data. This could lead to unauthorized access to sensitive user information, potential data breaches, and violation of user privacy.

 def get_user(self, validated_token: Token) -> AuthUser:
        """
        Attempts to find and return a user using the given validated token.
        """
        try:
            user_id = validated_token[api_settings.USER_ID_CLAIM]
        except KeyError:
            raise InvalidToken(_("Token contained no recognizable user identification"))

        try:
            user = self.user_model.objects.get(**{api_settings.USER_ID_FIELD: user_id})
        except self.user_model.DoesNotExist:
            raise AuthenticationFailed(_("User not found"), code="user_not_found")

        if not user.is_active:
            raise AuthenticationFailed(_("User is inactive"), code="user_inactive")

        if api_settings.CHECK_REVOKE_TOKEN:
            if validated_token.get(
                api_settings.REVOKE_TOKEN_CLAIM
            ) != get_md5_hash_password(user.password):
                raise AuthenticationFailed(
                    _("The user's password has been changed."), code="password_changed"
                )

        return user

POC

  1. Obtain a valid JWT token for your account.
  2. Decode the JWT (without verifying the signature) to access its payload.
  3. Modify the value of the USER_ID_CLAIM in the payload to the ID of a target user.
  4. Re-encode the JWT (the signature will be invalid, but that's not checked in this vulnerability).
  5. Send an API request with the modified JWT in the Authorization header.
  6. The server will process the request and return data for the target user, despite the
    JWT being for a different user.
    Example HTTP request: GET /api/user/profile
    HTTP/1.1 Host: example.com Authorization: Bearer
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiVEFSR0VUX1VTRVJfSUQiLCJleHA
    iOjE2MTY3NjY2MjB9.INVALID_SIGNATURE

IMPACT
This issue could potentially lead to unauthorised access to users personal information, the only thing that one attacker has to do is to find a valid USER ID.

@adamJLev
Copy link

adamJLev commented Nov 4, 2024

maybe im not quite understanding correctly, but how would this work when the JWT token is signed with the private key and then verified ? does this somehow work around the JWT signature verification?

@AlexanderNeilson
Copy link

AlexanderNeilson commented Nov 4, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants