From 0f193887d362f919cb17b1f1f9ece0c67b97684d Mon Sep 17 00:00:00 2001 From: Jon Ekdahl Date: Fri, 25 Mar 2016 23:03:06 +0100 Subject: [PATCH] Fix verification of unsigned tokens (fix #185) --- index.js | 10 ++++++++-- test/verify.tests.js | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 9dfbca9..cbda155 100644 --- a/index.js +++ b/index.js @@ -172,14 +172,20 @@ JWT.verify = function(jwtString, secretOrPublicKey, options, callback) { return done(new JsonWebTokenError('jwt malformed')); } - if (parts[2].trim() === '' && secretOrPublicKey){ + var hasSignature = parts[2].trim() !== ''; + + if (!hasSignature && secretOrPublicKey){ return done(new JsonWebTokenError('jwt signature is required')); } - if (!secretOrPublicKey) { + if (hasSignature && !secretOrPublicKey) { return done(new JsonWebTokenError('secret or public key must be provided')); } + if (!hasSignature && !options.algorithms) { + options.algorithms = ['none']; + } + if (!options.algorithms) { options.algorithms = ~secretOrPublicKey.toString().indexOf('BEGIN CERTIFICATE') || ~secretOrPublicKey.toString().indexOf('BEGIN PUBLIC KEY') ? diff --git a/test/verify.tests.js b/test/verify.tests.js index cb71137..bd8d9f7 100644 --- a/test/verify.tests.js +++ b/test/verify.tests.js @@ -28,6 +28,24 @@ describe('verify', function() { }); }); + it('should be able to validate unsigned token', function (done) { + var header = { alg: 'none' }; + var payload = { iat: Math.floor(Date.now() / 1000 ) }; + + var signed = jws.sign({ + header: header, + payload: payload, + secret: priv, + encoding: 'utf8' + }); + + jwt.verify(signed, null, {typ: 'JWT'}, function(err, p) { + assert.isNull(err); + assert.deepEqual(p, payload); + done(); + }); + }); + describe('expiration', function () { // { foo: 'bar', iat: 1437018582, exp: 1437018583 } var token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJiYXIiLCJpYXQiOjE0MzcwMTg1ODIsImV4cCI6MTQzNzAxODU4M30.NmMv7sXjM1dW0eALNXud8LoXknZ0mH14GtnFclwJv0s';