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 da35fa52..d05be737 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 161eb2dd..852bae42 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 612d171b..66992307 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 94360f6b..a5ec1f6d 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 5bf8df7f..0ff84d70 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 1aa5cda7..fd119b4f 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 3bd8c130..5964d2af 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 42633ade..7aa3d0fe 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 c56eea30..454b800b 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 75e8a024..cd6755af 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'); });