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: noneattack). ✍️❌
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.- Python
- Java
- .NET(C#)
- PHP
- Node.js
- Ruby
Framework Context
Using libraries likePyJWT 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 ifalg is none.Mitigation and Best Practices
Always usejwt.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: nonein 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.

