From 2890d672b90e22f533772d1fdeefe9c5172aceb3 Mon Sep 17 00:00:00 2001 From: Vansh Sharma Date: Wed, 25 Mar 2026 15:46:12 +0530 Subject: [PATCH] fix: wrap crypto TypeError in JsonWebTokenError for EC/RSA signatures When verifying a JWT with EC or RSA algorithms, malformed signatures could cause jws.verify() to throw a raw TypeError from the underlying Node.js crypto module (e.g. 'ES512 signatures must be 132 bytes, saw 131') instead of a JsonWebTokenError. This TypeError was passed directly to done(e) and would surface to callers as an undocumented error type, breaking any code that catches JsonWebTokenError to handle invalid-signature scenarios. Fix: in the jws.verify() catch block, check if the thrown error is already a JsonWebTokenError; if not, wrap it in new JsonWebTokenError('invalid signature') so callers always receive the documented, consistent error type. Fixes #767 --- verify.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/verify.js b/verify.js index cdbfdc4..7fddfb7 100644 --- a/verify.js +++ b/verify.js @@ -164,7 +164,14 @@ module.exports = function (jwtString, secretOrPublicKey, options, callback) { try { valid = jws.verify(jwtString, decodedToken.header.alg, secretOrPublicKey); } catch (e) { - return done(e); + // Wrap low-level crypto errors (e.g. TypeError from malformed EC/RSA + // signatures) in a JsonWebTokenError so callers always receive a + // consistent, documented error type instead of an undocumented TypeError. + // See: https://github.com/auth0/node-jsonwebtoken/issues/767 + if (e instanceof JsonWebTokenError) { + return done(e); + } + return done(new JsonWebTokenError('invalid signature')); } if (!valid) { @@ -208,8 +215,8 @@ module.exports = function (jwtString, secretOrPublicKey, options, callback) { if (options.issuer) { const invalid_issuer = - (typeof options.issuer === 'string' && payload.iss !== options.issuer) || - (Array.isArray(options.issuer) && options.issuer.indexOf(payload.iss) === -1); + (typeof options.issuer === 'string' && payload.iss !== options.issuer) || + (Array.isArray(options.issuer) && options.issuer.indexOf(payload.iss) === -1); if (invalid_issuer) { return done(new JsonWebTokenError('jwt issuer invalid. expected: ' + options.issuer));