Looking for the vulnerability index of Invicti's legacy products?
JWT Signature Bypass via unvalidated jwk parameter - Vulnerability Database

JWT Signature Bypass via unvalidated jwk parameter

Description

This vulnerability occurs when a JSON Web Token (JWT) implementation fails to properly validate the 'jwk' (JSON Web Key) parameter in the token header. The 'jwk' parameter allows the token itself to specify which public key should be used to verify its signature. Without strict validation, an attacker can embed their own cryptographic key in the token header and use the corresponding private key to sign malicious tokens. This effectively bypasses the signature verification mechanism, allowing attackers to forge valid-looking JWTs with arbitrary claims and payloads.

Remediation

Immediately disable support for the 'jwk' header parameter in your JWT validation logic unless there is an explicit and documented business requirement for it. Most applications should rely on a pre-configured, trusted key store rather than accepting keys embedded in tokens.

If you must support the 'jwk' parameter, implement the following controls:
1. Maintain a whitelist of trusted public keys and verify that any 'jwk' parameter matches an entry in this whitelist
2. Implement key pinning to ensure only known, trusted keys are accepted
3. Add additional validation to verify the key's origin and authenticity

Example secure validation (Node.js with jsonwebtoken library):

const jwt = require('jsonwebtoken');
const fs = require('fs');

// Load trusted public key from secure location
const trustedPublicKey = fs.readFileSync('path/to/trusted-public-key.pem');

function verifyToken(token) {
  try {
    // Decode header without verification to check for jwk parameter
    const decoded = jwt.decode(token, { complete: true });
    
    // Reject tokens with jwk parameter
    if (decoded.header.jwk) {
      throw new Error('jwk parameter not supported');
    }
    
    // Verify using only trusted key from server configuration
    const payload = jwt.verify(token, trustedPublicKey, {
      algorithms: ['RS256'] // Explicitly specify allowed algorithms
    });
    
    return payload;
  } catch (error) {
    throw new Error('Token validation failed: ' + error.message);
  }
}

Review all JWT validation code to ensure signatures are verified against keys from trusted, server-side sources only, never from user-controlled input.

Related Vulnerabilities