Skip to content

Commit d85caec

Browse files
author
Dan Pantry
committed
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'.
1 parent 5f10bf9 commit d85caec

10 files changed

+25
-25
lines changed

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ jwt.verify(token, getKey, options, function(err, decoded) {
231231

232232
```
233233

234-
### jwt.decode(token [, options])
234+
### jwt.unsafeDecode(token [, options])
235235

236236
(Synchronous) Returns the decoded payload without verifying if the signature is valid.
237237

@@ -251,10 +251,10 @@ Example
251251

252252
```js
253253
// get the decoded payload ignoring signature, no secretOrPrivateKey needed
254-
var decoded = jwt.decode(token);
254+
var decoded = jwt.unsafeDecode(token);
255255

256256
// get the decoded payload and header
257-
var decoded = jwt.decode(token, {complete: true});
257+
var decoded = jwt.unsafeDecode(token, {complete: true});
258258
console.log(decoded.header);
259259
console.log(decoded.payload)
260260
```

index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module.exports = {
2-
decode: require('./decode'),
2+
unsafeDecode: require('./decode'),
33
verify: require('./verify'),
44
sign: require('./sign'),
55
JsonWebTokenError: require('./lib/JsonWebTokenError'),

test/buffer.tests.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ describe('buffer payload', function () {
55
it('should work', function () {
66
var payload = new Buffer('TkJyotZe8NFpgdfnmgINqg==', 'base64');
77
var token = jwt.sign(payload, "signing key");
8-
assert.equal(jwt.decode(token), payload.toString());
8+
assert.equal(jwt.unsafeDecode(token), payload.toString());
99
});
1010
});

test/claim-exp.test.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ describe('expires', function() {
235235
// TODO an exp of -Infinity should fail validation
236236
it('should set null "exp" when given -Infinity', function (done) {
237237
signWithExpiresIn(undefined, {exp: -Infinity}, (err, token) => {
238-
const decoded = jwt.decode(token);
238+
const decoded = jwt.unsafeDecode(token);
239239
testUtils.asyncCheck(done, () => {
240240
expect(err).to.be.null;
241241
expect(decoded).to.have.property('exp', null);
@@ -246,7 +246,7 @@ describe('expires', function() {
246246
// TODO an exp of Infinity should fail validation
247247
it('should set null "exp" when given value Infinity', function (done) {
248248
signWithExpiresIn(undefined, {exp: Infinity}, (err, token) => {
249-
const decoded = jwt.decode(token);
249+
const decoded = jwt.unsafeDecode(token);
250250
testUtils.asyncCheck(done, () => {
251251
expect(err).to.be.null;
252252
expect(decoded).to.have.property('exp', null);
@@ -257,7 +257,7 @@ describe('expires', function() {
257257
// TODO an exp of NaN should fail validation
258258
it('should set null "exp" when given value NaN', function (done) {
259259
signWithExpiresIn(undefined, {exp: NaN}, (err, token) => {
260-
const decoded = jwt.decode(token);
260+
const decoded = jwt.unsafeDecode(token);
261261
testUtils.asyncCheck(done, () => {
262262
expect(err).to.be.null;
263263
expect(decoded).to.have.property('exp', null);

test/claim-iat.test.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ describe('issue at', function() {
149149
signWithIssueAt(testCase.iat, testCase.options, (err, token) => {
150150
testUtils.asyncCheck(done, () => {
151151
expect(err).to.be.null;
152-
expect(jwt.decode(token).iat).to.equal(testCase.expectedIssueAt);
152+
expect(jwt.unsafeDecode(token).iat).to.equal(testCase.expectedIssueAt);
153153
});
154154
});
155155
});
@@ -254,7 +254,7 @@ describe('issue at', function() {
254254
const payload = 'string payload';
255255
const options = {algorithm: 'none'};
256256
testUtils.signJWTHelper(payload, 'secret', options, (err, token) => {
257-
const decoded = jwt.decode(token);
257+
const decoded = jwt.unsafeDecode(token);
258258
testUtils.asyncCheck(done, () => {
259259
expect(err).to.be.null;
260260
expect(decoded).to.equal(payload);
@@ -266,7 +266,7 @@ describe('issue at', function() {
266266
const payload = '{}';
267267
const options = {algorithm: 'none', header: {typ: 'JWT'}};
268268
testUtils.signJWTHelper(payload, 'secret', options, (err, token) => {
269-
const decoded = jwt.decode(token);
269+
const decoded = jwt.unsafeDecode(token);
270270
testUtils.asyncCheck(done, () => {
271271
expect(err).to.equal(null);
272272
expect(JSON.stringify(decoded)).to.equal(payload);

test/claim-nbf.test.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ describe('not before', function() {
232232
// TODO an nbf of -Infinity should fail validation
233233
it('should set null "nbf" when given -Infinity', function (done) {
234234
signWithNotBefore(undefined, {nbf: -Infinity}, (err, token) => {
235-
const decoded = jwt.decode(token);
235+
const decoded = jwt.unsafeDecode(token);
236236
testUtils.asyncCheck(done, () => {
237237
expect(err).to.be.null;
238238
expect(decoded).to.have.property('nbf', null);
@@ -243,7 +243,7 @@ describe('not before', function() {
243243
// TODO an nbf of Infinity should fail validation
244244
it('should set null "nbf" when given value Infinity', function (done) {
245245
signWithNotBefore(undefined, {nbf: Infinity}, (err, token) => {
246-
const decoded = jwt.decode(token);
246+
const decoded = jwt.unsafeDecode(token);
247247
testUtils.asyncCheck(done, () => {
248248
expect(err).to.be.null;
249249
expect(decoded).to.have.property('nbf', null);
@@ -254,7 +254,7 @@ describe('not before', function() {
254254
// TODO an nbf of NaN should fail validation
255255
it('should set null "nbf" when given value NaN', function (done) {
256256
signWithNotBefore(undefined, {nbf: NaN}, (err, token) => {
257-
const decoded = jwt.decode(token);
257+
const decoded = jwt.unsafeDecode(token);
258258
testUtils.asyncCheck(done, () => {
259259
expect(err).to.be.null;
260260
expect(decoded).to.have.property('nbf', null);
@@ -337,4 +337,4 @@ describe('not before', function() {
337337
});
338338
});
339339
});
340-
});
340+
});

test/decoding.tests.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ var expect = require('chai').expect;
44
describe('decoding', function() {
55

66
it('should not crash when decoding a null token', function () {
7-
var decoded = jwt.decode("null");
7+
var decoded = jwt.unsafeDecode("null");
88
expect(decoded).to.equal(null);
99
});
1010

test/header-kid.test.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ describe('keyid', function() {
5757
it('should not add "kid" header when "keyid" option not provided', function(done) {
5858
signWithKeyId(undefined, {}, (err, token) => {
5959
testUtils.asyncCheck(done, () => {
60-
const decoded = jwt.decode(token, {complete: true});
60+
const decoded = jwt.unsafeDecode(token, {complete: true});
6161
expect(err).to.be.null;
6262
expect(decoded.header).to.not.have.property('kid');
6363
});
@@ -67,7 +67,7 @@ describe('keyid', function() {
6767
it('should add "kid" header when "keyid" option is provided and an object payload', function(done) {
6868
signWithKeyId('foo', {}, (err, token) => {
6969
testUtils.asyncCheck(done, () => {
70-
const decoded = jwt.decode(token, {complete: true});
70+
const decoded = jwt.unsafeDecode(token, {complete: true});
7171
expect(err).to.be.null;
7272
expect(decoded.header).to.have.property('kid', 'foo');
7373
});
@@ -77,7 +77,7 @@ describe('keyid', function() {
7777
it('should add "kid" header when "keyid" option is provided and a Buffer payload', function(done) {
7878
signWithKeyId('foo', new Buffer('a Buffer payload'), (err, token) => {
7979
testUtils.asyncCheck(done, () => {
80-
const decoded = jwt.decode(token, {complete: true});
80+
const decoded = jwt.unsafeDecode(token, {complete: true});
8181
expect(err).to.be.null;
8282
expect(decoded.header).to.have.property('kid', 'foo');
8383
});
@@ -87,7 +87,7 @@ describe('keyid', function() {
8787
it('should add "kid" header when "keyid" option is provided and a string payload', function(done) {
8888
signWithKeyId('foo', 'a string payload', (err, token) => {
8989
testUtils.asyncCheck(done, () => {
90-
const decoded = jwt.decode(token, {complete: true});
90+
const decoded = jwt.unsafeDecode(token, {complete: true});
9191
expect(err).to.be.null;
9292
expect(decoded.header).to.have.property('kid', 'foo');
9393
});

test/jwt.asymmetric_signing.tests.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ describe('Asymmetric Algorithms', function(){
148148

149149
describe('when decoding a invalid jwt token', function () {
150150
it('should return null', function (done) {
151-
var payload = jwt.decode('whatever.token');
151+
var payload = jwt.unsafeDecode('whatever.token');
152152
assert.isNull(payload);
153153
done();
154154
});
@@ -158,14 +158,14 @@ describe('Asymmetric Algorithms', function(){
158158
it('should return the payload', function (done) {
159159
var obj = { foo: 'bar' };
160160
var token = jwt.sign(obj, priv, { algorithm: algorithm });
161-
var payload = jwt.decode(token);
161+
var payload = jwt.unsafeDecode(token);
162162
assert.equal(payload.foo, obj.foo);
163163
done();
164164
});
165165
it('should return the header and payload and signature if complete option is set', function (done) {
166166
var obj = { foo: 'bar' };
167167
var token = jwt.sign(obj, priv, { algorithm: algorithm });
168-
var decoded = jwt.decode(token, { complete: true });
168+
var decoded = jwt.unsafeDecode(token, { complete: true });
169169
assert.equal(decoded.payload.foo, obj.foo);
170170
assert.deepEqual(decoded.header, { typ: 'JWT', alg: algorithm });
171171
assert.ok(typeof decoded.signature == 'string');

test/set_headers.tests.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ describe('set header', function() {
55

66
it('should add the header', function () {
77
var token = jwt.sign({foo: 123}, '123', { header: { foo: 'bar' } });
8-
var decoded = jwt.decode(token, {complete: true});
8+
var decoded = jwt.unsafeDecode(token, {complete: true});
99
expect(decoded.header.foo).to.equal('bar');
1010
});
1111

1212
it('should allow overriding header', function () {
1313
var token = jwt.sign({foo: 123}, '123', { header: { alg: 'HS512' } });
14-
var decoded = jwt.decode(token, {complete: true});
14+
var decoded = jwt.unsafeDecode(token, {complete: true});
1515
expect(decoded.header.alg).to.equal('HS512');
1616
});
1717

0 commit comments

Comments
 (0)