From d85caec039d6f9f22beaef60afcf1307ea3fa45d Mon Sep 17 00:00:00 2001 From: Dan Pantry Date: Wed, 2 Sep 2020 11:27:58 +0100 Subject: [PATCH] rename 'decode' to 'unsafeDecode' 'decode' is often reached to by well-meaning developers who assume that the call is safe. Unfortunately, this leads to untrusted JWTs being accepted as otherwise acceptable input. Renaming 'decode' to 'unsafeDecode' signals to the end user that the method they are calling is indeed unsafe without them having to remember the difference between 'decode' and 'verify'. --- README.md | 6 +++--- index.js | 2 +- test/buffer.tests.js | 2 +- test/claim-exp.test.js | 6 +++--- test/claim-iat.test.js | 6 +++--- test/claim-nbf.test.js | 8 ++++---- test/decoding.tests.js | 2 +- test/header-kid.test.js | 8 ++++---- test/jwt.asymmetric_signing.tests.js | 6 +++--- test/set_headers.tests.js | 4 ++-- 10 files changed, 25 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index da35fa5..d05be73 100644 --- a/README.md +++ b/README.md @@ -231,7 +231,7 @@ jwt.verify(token, getKey, options, function(err, decoded) { ``` -### jwt.decode(token [, options]) +### jwt.unsafeDecode(token [, options]) (Synchronous) Returns the decoded payload without verifying if the signature is valid. @@ -251,10 +251,10 @@ Example ```js // get the decoded payload ignoring signature, no secretOrPrivateKey needed -var decoded = jwt.decode(token); +var decoded = jwt.unsafeDecode(token); // get the decoded payload and header -var decoded = jwt.decode(token, {complete: true}); +var decoded = jwt.unsafeDecode(token, {complete: true}); console.log(decoded.header); console.log(decoded.payload) ``` diff --git a/index.js b/index.js index 161eb2d..852bae4 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ module.exports = { - decode: require('./decode'), + unsafeDecode: require('./decode'), verify: require('./verify'), sign: require('./sign'), JsonWebTokenError: require('./lib/JsonWebTokenError'), diff --git a/test/buffer.tests.js b/test/buffer.tests.js index 612d171..6699230 100644 --- a/test/buffer.tests.js +++ b/test/buffer.tests.js @@ -5,6 +5,6 @@ describe('buffer payload', function () { it('should work', function () { var payload = new Buffer('TkJyotZe8NFpgdfnmgINqg==', 'base64'); var token = jwt.sign(payload, "signing key"); - assert.equal(jwt.decode(token), payload.toString()); + assert.equal(jwt.unsafeDecode(token), payload.toString()); }); }); diff --git a/test/claim-exp.test.js b/test/claim-exp.test.js index 94360f6..a5ec1f6 100644 --- a/test/claim-exp.test.js +++ b/test/claim-exp.test.js @@ -235,7 +235,7 @@ describe('expires', function() { // TODO an exp of -Infinity should fail validation it('should set null "exp" when given -Infinity', function (done) { signWithExpiresIn(undefined, {exp: -Infinity}, (err, token) => { - const decoded = jwt.decode(token); + const decoded = jwt.unsafeDecode(token); testUtils.asyncCheck(done, () => { expect(err).to.be.null; expect(decoded).to.have.property('exp', null); @@ -246,7 +246,7 @@ describe('expires', function() { // TODO an exp of Infinity should fail validation it('should set null "exp" when given value Infinity', function (done) { signWithExpiresIn(undefined, {exp: Infinity}, (err, token) => { - const decoded = jwt.decode(token); + const decoded = jwt.unsafeDecode(token); testUtils.asyncCheck(done, () => { expect(err).to.be.null; expect(decoded).to.have.property('exp', null); @@ -257,7 +257,7 @@ describe('expires', function() { // TODO an exp of NaN should fail validation it('should set null "exp" when given value NaN', function (done) { signWithExpiresIn(undefined, {exp: NaN}, (err, token) => { - const decoded = jwt.decode(token); + const decoded = jwt.unsafeDecode(token); testUtils.asyncCheck(done, () => { expect(err).to.be.null; expect(decoded).to.have.property('exp', null); diff --git a/test/claim-iat.test.js b/test/claim-iat.test.js index 5bf8df7..0ff84d7 100644 --- a/test/claim-iat.test.js +++ b/test/claim-iat.test.js @@ -149,7 +149,7 @@ describe('issue at', function() { signWithIssueAt(testCase.iat, testCase.options, (err, token) => { testUtils.asyncCheck(done, () => { expect(err).to.be.null; - expect(jwt.decode(token).iat).to.equal(testCase.expectedIssueAt); + expect(jwt.unsafeDecode(token).iat).to.equal(testCase.expectedIssueAt); }); }); }); @@ -254,7 +254,7 @@ describe('issue at', function() { const payload = 'string payload'; const options = {algorithm: 'none'}; testUtils.signJWTHelper(payload, 'secret', options, (err, token) => { - const decoded = jwt.decode(token); + const decoded = jwt.unsafeDecode(token); testUtils.asyncCheck(done, () => { expect(err).to.be.null; expect(decoded).to.equal(payload); @@ -266,7 +266,7 @@ describe('issue at', function() { const payload = '{}'; const options = {algorithm: 'none', header: {typ: 'JWT'}}; testUtils.signJWTHelper(payload, 'secret', options, (err, token) => { - const decoded = jwt.decode(token); + const decoded = jwt.unsafeDecode(token); testUtils.asyncCheck(done, () => { expect(err).to.equal(null); expect(JSON.stringify(decoded)).to.equal(payload); diff --git a/test/claim-nbf.test.js b/test/claim-nbf.test.js index 1aa5cda..fd119b4 100644 --- a/test/claim-nbf.test.js +++ b/test/claim-nbf.test.js @@ -232,7 +232,7 @@ describe('not before', function() { // TODO an nbf of -Infinity should fail validation it('should set null "nbf" when given -Infinity', function (done) { signWithNotBefore(undefined, {nbf: -Infinity}, (err, token) => { - const decoded = jwt.decode(token); + const decoded = jwt.unsafeDecode(token); testUtils.asyncCheck(done, () => { expect(err).to.be.null; expect(decoded).to.have.property('nbf', null); @@ -243,7 +243,7 @@ describe('not before', function() { // TODO an nbf of Infinity should fail validation it('should set null "nbf" when given value Infinity', function (done) { signWithNotBefore(undefined, {nbf: Infinity}, (err, token) => { - const decoded = jwt.decode(token); + const decoded = jwt.unsafeDecode(token); testUtils.asyncCheck(done, () => { expect(err).to.be.null; expect(decoded).to.have.property('nbf', null); @@ -254,7 +254,7 @@ describe('not before', function() { // TODO an nbf of NaN should fail validation it('should set null "nbf" when given value NaN', function (done) { signWithNotBefore(undefined, {nbf: NaN}, (err, token) => { - const decoded = jwt.decode(token); + const decoded = jwt.unsafeDecode(token); testUtils.asyncCheck(done, () => { expect(err).to.be.null; expect(decoded).to.have.property('nbf', null); @@ -337,4 +337,4 @@ describe('not before', function() { }); }); }); -}); \ No newline at end of file +}); diff --git a/test/decoding.tests.js b/test/decoding.tests.js index 3bd8c13..5964d2a 100644 --- a/test/decoding.tests.js +++ b/test/decoding.tests.js @@ -4,7 +4,7 @@ var expect = require('chai').expect; describe('decoding', function() { it('should not crash when decoding a null token', function () { - var decoded = jwt.decode("null"); + var decoded = jwt.unsafeDecode("null"); expect(decoded).to.equal(null); }); diff --git a/test/header-kid.test.js b/test/header-kid.test.js index 42633ad..7aa3d0f 100644 --- a/test/header-kid.test.js +++ b/test/header-kid.test.js @@ -57,7 +57,7 @@ describe('keyid', function() { it('should not add "kid" header when "keyid" option not provided', function(done) { signWithKeyId(undefined, {}, (err, token) => { testUtils.asyncCheck(done, () => { - const decoded = jwt.decode(token, {complete: true}); + const decoded = jwt.unsafeDecode(token, {complete: true}); expect(err).to.be.null; expect(decoded.header).to.not.have.property('kid'); }); @@ -67,7 +67,7 @@ describe('keyid', function() { it('should add "kid" header when "keyid" option is provided and an object payload', function(done) { signWithKeyId('foo', {}, (err, token) => { testUtils.asyncCheck(done, () => { - const decoded = jwt.decode(token, {complete: true}); + const decoded = jwt.unsafeDecode(token, {complete: true}); expect(err).to.be.null; expect(decoded.header).to.have.property('kid', 'foo'); }); @@ -77,7 +77,7 @@ describe('keyid', function() { it('should add "kid" header when "keyid" option is provided and a Buffer payload', function(done) { signWithKeyId('foo', new Buffer('a Buffer payload'), (err, token) => { testUtils.asyncCheck(done, () => { - const decoded = jwt.decode(token, {complete: true}); + const decoded = jwt.unsafeDecode(token, {complete: true}); expect(err).to.be.null; expect(decoded.header).to.have.property('kid', 'foo'); }); @@ -87,7 +87,7 @@ describe('keyid', function() { it('should add "kid" header when "keyid" option is provided and a string payload', function(done) { signWithKeyId('foo', 'a string payload', (err, token) => { testUtils.asyncCheck(done, () => { - const decoded = jwt.decode(token, {complete: true}); + const decoded = jwt.unsafeDecode(token, {complete: true}); expect(err).to.be.null; expect(decoded.header).to.have.property('kid', 'foo'); }); diff --git a/test/jwt.asymmetric_signing.tests.js b/test/jwt.asymmetric_signing.tests.js index c56eea3..454b800 100644 --- a/test/jwt.asymmetric_signing.tests.js +++ b/test/jwt.asymmetric_signing.tests.js @@ -148,7 +148,7 @@ describe('Asymmetric Algorithms', function(){ describe('when decoding a invalid jwt token', function () { it('should return null', function (done) { - var payload = jwt.decode('whatever.token'); + var payload = jwt.unsafeDecode('whatever.token'); assert.isNull(payload); done(); }); @@ -158,14 +158,14 @@ describe('Asymmetric Algorithms', function(){ it('should return the payload', function (done) { var obj = { foo: 'bar' }; var token = jwt.sign(obj, priv, { algorithm: algorithm }); - var payload = jwt.decode(token); + var payload = jwt.unsafeDecode(token); assert.equal(payload.foo, obj.foo); done(); }); it('should return the header and payload and signature if complete option is set', function (done) { var obj = { foo: 'bar' }; var token = jwt.sign(obj, priv, { algorithm: algorithm }); - var decoded = jwt.decode(token, { complete: true }); + var decoded = jwt.unsafeDecode(token, { complete: true }); assert.equal(decoded.payload.foo, obj.foo); assert.deepEqual(decoded.header, { typ: 'JWT', alg: algorithm }); assert.ok(typeof decoded.signature == 'string'); diff --git a/test/set_headers.tests.js b/test/set_headers.tests.js index 75e8a02..cd6755a 100644 --- a/test/set_headers.tests.js +++ b/test/set_headers.tests.js @@ -5,13 +5,13 @@ describe('set header', function() { it('should add the header', function () { var token = jwt.sign({foo: 123}, '123', { header: { foo: 'bar' } }); - var decoded = jwt.decode(token, {complete: true}); + var decoded = jwt.unsafeDecode(token, {complete: true}); expect(decoded.header.foo).to.equal('bar'); }); it('should allow overriding header', function () { var token = jwt.sign({foo: 123}, '123', { header: { alg: 'HS512' } }); - var decoded = jwt.decode(token, {complete: true}); + var decoded = jwt.unsafeDecode(token, {complete: true}); expect(decoded.header.alg).to.equal('HS512'); });