python.jwt.security.unverified-jwt-decode.unverified-jwt-decode

profile photo of returntocorpreturntocorp
Author
7,452
Download Count*

Detected JWT token decoded with 'verify=False'. This bypasses any integrity checks for the token which means the token could be tampered with by malicious actors. Ensure that the JWT token is verified.

Run Locally

Run in CI

Defintion

rules:
  - id: unverified-jwt-decode
    pattern: |
      jwt.decode(..., verify=False, ...)
    message: Detected JWT token decoded with 'verify=False'. This bypasses any
      integrity checks for the token which means the token could be tampered
      with by malicious actors. Ensure that the JWT token is verified.
    metadata:
      owasp:
        - A02:2017 - Broken Authentication
        - A07:2021 - Identification and Authentication Failures
      cwe:
        - "CWE-287: Improper Authentication"
      references:
        - https://github.com/we45/Vulnerable-Flask-App/blob/752ee16087c0bfb79073f68802d907569a1f0df7/app/app.py#L96
      category: security
      technology:
        - jwt
      cwe2022-top25: true
      cwe2021-top25: true
      subcategory:
        - audit
      likelihood: MEDIUM
      impact: MEDIUM
      confidence: MEDIUM
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Improper Authentication
    fix-regex:
      regex: (verify\s*=\s*)False
      replacement: \1True
    severity: ERROR
    languages:
      - python

Examples

unverified-jwt-decode.py

# cf. https://github.com/we45/Vulnerable-Flask-App/blob/752ee16087c0bfb79073f68802d907569a1f0df7/app/app.py#L96

import jwt
from jwt.exceptions import DecodeError, MissingRequiredClaimError, InvalidKeyError

def verify_jwt(token):
    try:
        # ok:unverified-jwt-decode
        decoded = jwt.decode(token, app.config['SECRET_KEY_HMAC'], verify=True, issuer = 'we45', leeway=10, algorithms=['HS256'])
        print("JWT Token from API: {0}".format(decoded))
        return True
    except DecodeError:
        print("Error in decoding token")
        return False
    except MissingRequiredClaimError as e:
        print('Claim required is missing: {0}'.format(e))
        return False

def insecure_verify(token):
    # ruleid:unverified-jwt-decode
    decoded = jwt.decode(token, verify = False)
    print(decoded)
    return True