HIGH jwt misconfigurationdjangohmac signatures

Jwt Misconfiguration in Django with Hmac Signatures

Jwt Misconfiguration in Django with Hmac Signatures — how this specific combination creates or exposes the vulnerability

JSON Web Tokens (JWT) are widely used for stateless authentication. When using HMAC signatures in Django, the security of the token depends on a strong shared secret and strict validation. Misconfiguration typically occurs when the secret is weak, hardcoded in source code, or accidentally exposed, or when the algorithm is not explicitly enforced during verification.

Consider this insecure example where a developer uses PyJWT without specifying algorithms and with a predictable secret:

import jwt
SECRET = "12345"  # weak and exposed

def create_token(user_id):
    return jwt.encode({"sub": user_id, "role": "user"}, SECRET, algorithm="HS256")

def decode_token(token):
    # Missing algorithms parameter; vulnerable to algorithm confusion
    return jwt.decode(token, SECRET, options={"verify_signature": False})

By disabling signature verification (verify_signature: False) or omitting the algorithms argument, the application can be tricked into accepting an unsigned token or a token signed with a different algorithm (e.g., none or RS256) if the library defaults are exploited. This is a classic JWT misconfiguration that maps to the OWASP API Security Top 10 category of Broken Object Level Authorization (BOLA/IDOR) and Authentication flaws.

Another common issue is logging or exposing the secret via error messages or debug endpoints. If an attacker can cause the application to reveal the secret—through information leakage or SSRF that reaches internal configuration—the integrity of all HMAC-signed tokens is compromised. middleBrick scans for such information exposure as part of its Data Exposure and Authentication checks, flagging weak secrets and unsafe token handling.

Additionally, missing audience (aud) and issuer (iss) claims allows token substitution across services. Without validating these claims, an attacker could reuse a token intended for one service on another service within the same ecosystem, escalating impact via BOLA/IDOR. middleBrick’s OpenAPI/Swagger analysis cross-references declared security schemes with runtime behavior to detect such gaps.

Insecure storage of the HMAC secret in environment variables that are inadvertently logged or included in client-side code also creates risk. middleBrick’s LLM/AI Security checks specifically look for secret leakage patterns and unsafe handling of tokens in outputs, ensuring that misconfigured token handling is surfaced with severity and remediation guidance.

Hmac Signatures-Specific Remediation in Django — concrete code fixes

To secure JWT handling with HMAC in Django, always specify allowed algorithms, validate all standard claims, and protect the secret. Use a strong, randomly generated secret stored securely (e.g., via Django settings from a secrets manager) and avoid disabling signature verification.

Here is a secure implementation example using PyJWT:

import jwt
from datetime import datetime, timedelta, timezone
from django.conf import settings

# Strong secret sourced from Django settings; keep it out of source code
SECRET_KEY = getattr(settings, "JWT_HMAC_SECRET", "")
ALGORITHM = "HS256"
AUDIENCE = "myapi.example.com"
ISSUER = "django-app.example.com"

def create_token(user_id: str) -> str:
    now = datetime.now(timezone.utc)
    payload = {
        "sub": user_id,
        "role": "user",
        "iat": now,
        "exp": now + timedelta(hours=1),
        "aud": AUDIENCE,
        "iss": ISSUER,
    }
    return jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM)

def decode_token(token: str) -> dict:
    return jwt.decode(
        token,
        SECRET_KEY,
        algorithms=[ALGORITHM],
        audience=AUDIENCE,
        issuer=ISSUER,
        options={"require": ["exp", "iat", "aud", "iss"]},
    )

Key points in the remediation:

  • Always pass algorithms=["HS256"] to jwt.decode to prevent algorithm confusion attacks.
  • Validate audience and issuer to ensure tokens are intended for your service.
  • Set short expiration times and use iat (issued at) to detect replay windows.
  • Never set verify_signature=False or omit the algorithms list.
  • Rotate the HMAC secret periodically and monitor for anomalies; middleBrick’s continuous monitoring in the Pro plan can alert on score drops related to authentication changes.

If you use Django REST Framework, integrate the token validation into permissions rather than views directly. For example:

from rest_framework.permissions import BasePermission
import jwt

class JWTAuthenticationPermission(BasePermission):
    def has_permission(self, request, view):
        auth = request.headers.get("Authorization")
        if not auth or not auth.startswith("Bearer "):
            return False
        token = auth.split(" ")[1]
        try:
            jwt.decode(
                token,
                settings.JWT_HMAC_SECRET,
                algorithms=["HS256"],
                audience=settings.JWT_AUDIENCE,
                issuer=settings.JWT_ISSUER,
            )
            return True
        except jwt.PyJWTError:
            return False

middleBrick’s GitHub Action can be added to CI/CD pipelines to fail builds if a scan detects weak secrets or missing algorithm constraints. The CLI provides JSON output for scripting: middlebrick scan <url>. For AI-assisted development, the MCP Server lets you scan APIs directly from your coding assistant, catching misconfigurations before deployment.

Related CWEs: authentication

CWE IDNameSeverity
CWE-287Improper Authentication CRITICAL
CWE-306Missing Authentication for Critical Function CRITICAL
CWE-307Brute Force HIGH
CWE-308Single-Factor Authentication MEDIUM
CWE-309Use of Password System for Primary Authentication MEDIUM
CWE-347Improper Verification of Cryptographic Signature HIGH
CWE-384Session Fixation HIGH
CWE-521Weak Password Requirements MEDIUM
CWE-613Insufficient Session Expiration MEDIUM
CWE-640Weak Password Recovery HIGH

Frequently Asked Questions

Why is specifying the algorithms parameter important when decoding JWTs with HMAC in Django?
Specifying algorithms prevents algorithm confusion attacks, where an attacker tricks the application into verifying a token with a weaker or unsigned algorithm (e.g., 'none' or 'RS256') if the library defaults are exploited.
How does middleBrick help detect JWT misconfigurations in Django applications using HMAC?
middleBrick runs checks for Authentication, Data Exposure, and LLM/AI Security, flagging weak secrets, missing claim validation, and unsafe token handling. Findings include severity and remediation guidance, and the Pro plan provides continuous monitoring for such issues.