Skip to main content

Overview

This vulnerability occurs when an application fails to properly validate cryptographic signatures or message authentication codes (MACs). This can happen in several ways:
  • Missing Verification: The application receives signed data but doesn’t check the signature at all.
  • Weak Algorithm Acceptance: The application accepts signatures using weak algorithms (like HMAC-SHA1) when stronger ones are expected.
  • Algorithm Confusion: The application trusts a parameter (often in the data itself, like a JWT header) that specifies which algorithm to use for verification, allowing an attacker to downgrade to a weak algorithm or even disable signature checks entirely (e.g., the JWT alg: none attack). ✍️❌

Business Impact

Failure to verify signatures properly allows attackers to tamper with data or impersonate legitimate senders.
  • Data Tampering: Signed messages, configurations, or tokens can be altered without detection.
  • Authentication Bypass: If signatures are used for authentication (like in JWTs), attackers can forge tokens to gain unauthorized access.
  • Impersonation: Attackers can craft messages that appear to come from a trusted source.

Reference Details

CWE ID: CWE-347 OWASP Top 10 (2021): A02:2021 - Cryptographic Failures Severity: High

Framework-Specific Analysis and Remediation

This is common with JSON Web Tokens (JWTs), SAML assertions, signed URLs, and any system where data integrity and authenticity rely on signatures. The key is to always verify the signature using a predetermined, strong algorithm configured on the server-side, and never trust algorithm information provided within the untrusted data itself.

Framework Context

Using libraries like PyJWT but failing to verify the signature or accepting the 'none' algorithm.

Vulnerable Scenario 1: Decoding JWT without Verification

Vulnerable Scenario 2: Accepting ‘none’ Algorithm

Older versions of PyJWT might have allowed this, or custom logic might bypass checks if alg is none.

Mitigation and Best Practices

Always use jwt.decode() with the key and algorithms parameters specified. Never set options={"verify_signature": False}. Explicitly list the only acceptable strong algorithms (e.g., ["HS256", "RS256"]) in the algorithms parameter to prevent downgrade attacks.

Secure Code Example

Testing Strategy

Write unit tests for your JWT decoding function.
  • Pass a token signed with the wrong key; assert decoding fails.
  • Pass a token with alg: none in the header; assert decoding fails.
  • Pass a token signed with an algorithm not in your ALLOWED_ALGORITHMS; assert decoding fails (InvalidAlgorithmError).
  • Pass a valid token; assert decoding succeeds.