📗
Application Security Manual
  • Intro
    • Start Here
  • Vulnerabilities & Code
    • Injection Vulnerabilities
      • SQL Injection
      • Server-Side Template Injection (SSTI)
      • XPath Injection
      • XML External Entity (XXE) Injection
      • HTTP Request Smuggling
      • Insecure Deserialization
    • Input-based Vulnerabilities
      • Cross-Site Scripting (XSS)
      • Content Security Policy (CSP) Misconfiguration
      • HTTP Parameter Pollution
    • Origin-related Vulnerabilities
      • Cross-Site Request Forgery (CSRF)
      • Server-Side Request Forgery (SSRF)
      • Cross-Origin Resource Sharing (CORS) Misconfiguration
    • Access-related Vulnerabilities
      • Insecure Direct Object References (IDOR)
      • Authorization Code Interception
      • Session Hijacking
      • Insufficient Transport Layer Security (TLS)
      • JSON Web Token (JWT) Vulnerabilities
      • Insecure Client-Side Storage of JWTs
    • Logic & Timing Vulnerabilities
      • Business Logic Flaws
      • Type Juggling (Loose Type Comparison)
      • Timing Attack
  • Design Review
    • Product Security Design Review Framework
    • Security Design Review Checklist
  • Concepts & Culture
    • Implementing SAST Through Security-Driven Developer Culture
    • Security as Code: Baking Security into DevOps
Powered by GitBook
On this page
  • Concept
  • Vulnerable Scenario
  • Explanation
  • Prevention
  • Conclusion
  1. Vulnerabilities & Code
  2. Access-related Vulnerabilities

JSON Web Token (JWT) Vulnerabilities

Concept

JSON Web Token (JWT) is a popular authentication and authorization mechanism used in web applications. It is a compact and self-contained way of securely transmitting information between parties as a JSON object. JWTs are commonly used for authentication, session management, and secure information exchange.

However, if JWT is not implemented securely or if certain vulnerabilities are present, attackers can exploit these weaknesses to gain unauthorized access, escalate privileges, or perform other malicious activities.

Vulnerable Scenario

Consider a web application that uses JWT for authentication and authorization. The application issues JWTs to users upon successful login and uses them to authenticate subsequent requests. However, the application has several vulnerabilities related to JWT handling.

Example Code (Vulnerable)

import jwt
from flask import Flask, request, jsonify

app = Flask(__name__)
app.config['SECRET_KEY'] = 'weak-secret-key'

@app.route('/login', methods=['POST'])
def login():
    username = request.json.get('username')
    password = request.json.get('password')
    
    if authenticate_user(username, password):
        payload = {'username': username, 'role': 'admin'}
        token = jwt.encode(payload, app.config['SECRET_KEY'], algorithm='HS256')
        return jsonify({'token': token})
    else:
        return jsonify({'message': 'Invalid credentials'}), 401

@app.route('/protected', methods=['GET'])
def protected():
    token = request.headers.get('Authorization')
    
    if token:
        try:
            payload = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])
            username = payload['username']
            return jsonify({'message': f'Welcome, {username}!'})
        except jwt.ExpiredSignatureError:
            return jsonify({'message': 'Token has expired'}), 401
        except jwt.InvalidTokenError:
            return jsonify({'message': 'Invalid token'}), 401
    else:
        return jsonify({'message': 'Token is missing'}), 401

if __name__ == '__main__':
    app.run()

Explanation

In this example, the web application uses JWT for authentication and authorization. However, it has several vulnerabilities that can be exploited:

  1. Weak secret key: The application uses a weak secret key ('weak-secret-key') to sign and verify JWTs. If an attacker discovers the secret key, they can forge valid JWTs and gain unauthorized access.

  2. Lack of token expiration: The application does not set an expiration time for the JWTs. This means that once a token is issued, it remains valid indefinitely, increasing the risk of unauthorized access if a token is stolen or leaked.

  3. Insufficient token validation: The application does not properly validate the JWT before accepting it. It only checks for the presence of the token in the Authorization header but does not verify the token's integrity or validity.

  4. Insecure token storage: The application does not securely store the JWT on the client-side. If an attacker gains access to the client-side storage (e.g., local storage or cookies), they can steal the token and use it to impersonate the user.

  5. Inappropriate use of JWT: The application uses JWT to store sensitive information, such as the user's role ('admin'), directly in the token payload. This information can be easily decoded and modified by an attacker, leading to privilege escalation.

Prevention

To mitigate the risks associated with JWT vulnerabilities, consider the following measures:

  1. Use strong secret keys: Generate strong and unique secret keys for signing and verifying JWTs. Use a combination of random characters, numbers, and symbols, and ensure the key is sufficiently long (e.g., at least 256 bits).

  2. Set token expiration: Always set an appropriate expiration time for JWTs using the exp claim. This limits the window of opportunity for attackers to use stolen or leaked tokens.

  3. Validate and verify tokens: Properly validate and verify JWTs on the server-side. Check the token's integrity, signature, and expiration. Use a secure library for JWT handling and avoid implementing custom token validation logic.

  4. Secure token storage: Store JWTs securely on the client-side. Use secure cookies with the HttpOnly and Secure flags set to prevent client-side access and ensure the tokens are transmitted over HTTPS.

  5. Avoid sensitive information in tokens: Do not store sensitive information, such as user roles or permissions, directly in the JWT payload. Instead, use token IDs or references to retrieve user information from a secure server-side storage.

  6. Implement token revocation: Provide mechanisms to revoke or invalidate tokens when necessary, such as when a user logs out or when a token is suspected to be compromised.

  7. Use secure algorithms: Use secure and strong algorithms for signing and encrypting JWTs, such as HMAC with SHA-256 (HS256) or RSA with SHA-256 (RS256).

Example Code (Secure)

import jwt
from datetime import datetime, timedelta
from flask import Flask, request, jsonify

app = Flask(__name__)
app.config['SECRET_KEY'] = 'strong-secret-key'
app.config['JWT_EXPIRATION_DELTA'] = timedelta(minutes=30)

@app.route('/login', methods=['POST'])
def login():
    username = request.json.get('username')
    password = request.json.get('password')
    
    if authenticate_user(username, password):
        payload = {'username': username, 'exp': datetime.utcnow() + app.config['JWT_EXPIRATION_DELTA']}
        token = jwt.encode(payload, app.config['SECRET_KEY'], algorithm='HS256')
        return jsonify({'token': token})
    else:
        return jsonify({'message': 'Invalid credentials'}), 401

@app.route('/protected', methods=['GET'])
def protected():
    token = request.headers.get('Authorization')
    
    if token:
        try:
            payload = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])
            username = payload['username']
            return jsonify({'message': f'Welcome, {username}!'})
        except jwt.ExpiredSignatureError:
            return jsonify({'message': 'Token has expired'}), 401
        except jwt.InvalidTokenError:
            return jsonify({'message': 'Invalid token'}), 401
    else:
        return jsonify({'message': 'Token is missing'}), 401

if __name__ == '__main__':
    app.run()

In the secure example, several improvements have been made:

  1. Strong secret key: The application uses a strong secret key ('strong-secret-key') for signing and verifying JWTs.

  2. Token expiration: The JWT includes an expiration time (exp) claim set to 30 minutes from the time of token issuance. This limits the validity period of the token.

  3. Token validation: The application properly validates and verifies the JWT using the jwt.decode() function, ensuring the token's integrity and validity.

  4. Secure token storage: The JWT is stored securely on the client-side using secure cookies or other secure storage mechanisms (not shown in the example).

  5. Sensitive information handling: The JWT payload only contains the username and expiration time, avoiding the inclusion of sensitive information like user roles.

Conclusion

JSON Web Token (JWT) is a powerful authentication and authorization mechanism, but it must be implemented securely to prevent vulnerabilities. Weak secret keys, lack of token expiration, insufficient token validation, insecure token storage, and inappropriate use of JWTs can lead to unauthorized access, privilege escalation, and other security risks.

To mitigate these risks, it is essential to use strong secret keys, set appropriate token expiration times, properly validate and verify tokens, store tokens securely, avoid storing sensitive information in tokens, implement token revocation mechanisms, and use secure algorithms for signing and encryption.

Developers should follow best practices and guidelines for secure JWT implementation and regularly update their knowledge of JWT security to stay ahead of emerging threats and vulnerabilities.

Semgrep Rule

Semgrep can be used to identify instances where JWT tokens are not properly validated or verified in the application.

rules:
  - id: jwt-missing-validation
    patterns:
      - pattern: |
          jwt.decode($TOKEN, ...)
      - pattern-not: |
          jwt.decode($TOKEN, $SECRET_KEY, ...)
    message: "Missing JWT token validation. Ensure the token is properly validated and verified using a secret key."
    languages:
      - python
    severity: ERROR

This Semgrep rule identifies code patterns where the jwt.decode() function is used to decode a JWT token but the secret key is not provided for validation. It suggests properly validating and verifying the token using a secret key to prevent JWT vulnerabilities.

Note that this rule is a starting point and may need to be expanded to cover other JWT-related vulnerabilities and best practices specific to your application. It is important to thoroughly review and test the JWT implementation to ensure it adheres to security guidelines and mitigates known risks.

PreviousInsufficient Transport Layer Security (TLS)NextInsecure Client-Side Storage of JWTs

Last updated 1 year ago