Skip to content

Commit 10046e1

Browse files
committed
Reject non-finite exp/nbf/iat values and tighten validation
1 parent ed59e76 commit 10046e1

4 files changed

Lines changed: 37 additions & 72 deletions

File tree

sign.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ const jws = require('jws');
55
const includes = require('lodash.includes');
66
const isBoolean = require('lodash.isboolean');
77
const isInteger = require('lodash.isinteger');
8-
const isNumber = require('lodash.isnumber');
98
const isPlainObject = require('lodash.isplainobject');
109
const isString = require('lodash.isstring');
1110
const once = require('lodash.once');
@@ -34,9 +33,9 @@ const sign_options_schema = {
3433
};
3534

3635
const registered_claims_schema = {
37-
iat: { isValid: isNumber, message: '"iat" should be a number of seconds' },
38-
exp: { isValid: isNumber, message: '"exp" should be a number of seconds' },
39-
nbf: { isValid: isNumber, message: '"nbf" should be a number of seconds' }
36+
iat: { isValid: function(value) { return typeof value === 'number' && Number.isFinite(value); }, message: '"iat" should be a number of seconds' },
37+
exp: { isValid: function(value) { return typeof value === 'number' && Number.isFinite(value); }, message: '"exp" should be a number of seconds' },
38+
nbf: { isValid: function(value) { return typeof value === 'number' && Number.isFinite(value); }, message: '"nbf" should be a number of seconds' }
4039
};
4140

4241
function validate(schema, allowUnknown, object, parameterName) {

test/claim-exp.test.js

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -231,35 +231,29 @@ describe('expires', function() {
231231
});
232232
});
233233

234-
// TODO an exp of -Infinity should fail validation
235-
it('should set null "exp" when given -Infinity', function (done) {
236-
signWithExpiresIn(undefined, {exp: -Infinity}, (err, token) => {
237-
const decoded = jwt.decode(token);
234+
it('should throw error when "exp" is -Infinity', function (done) {
235+
signWithExpiresIn(undefined, {exp: -Infinity}, (err) => {
238236
testUtils.asyncCheck(done, () => {
239-
expect(err).to.be.null;
240-
expect(decoded).to.have.property('exp', null);
237+
expect(err).to.be.instanceOf(Error);
238+
expect(err).to.have.property('message', '"exp" should be a number of seconds');
241239
});
242240
});
243241
});
244242

245-
// TODO an exp of Infinity should fail validation
246-
it('should set null "exp" when given value Infinity', function (done) {
247-
signWithExpiresIn(undefined, {exp: Infinity}, (err, token) => {
248-
const decoded = jwt.decode(token);
243+
it('should throw error when "exp" is Infinity', function (done) {
244+
signWithExpiresIn(undefined, {exp: Infinity}, (err) => {
249245
testUtils.asyncCheck(done, () => {
250-
expect(err).to.be.null;
251-
expect(decoded).to.have.property('exp', null);
246+
expect(err).to.be.instanceOf(Error);
247+
expect(err).to.have.property('message', '"exp" should be a number of seconds');
252248
});
253249
});
254250
});
255251

256-
// TODO an exp of NaN should fail validation
257-
it('should set null "exp" when given value NaN', function (done) {
258-
signWithExpiresIn(undefined, {exp: NaN}, (err, token) => {
259-
const decoded = jwt.decode(token);
252+
it('should throw error when "exp" is NaN', function (done) {
253+
signWithExpiresIn(undefined, {exp: NaN}, (err) => {
260254
testUtils.asyncCheck(done, () => {
261-
expect(err).to.be.null;
262-
expect(decoded).to.have.property('exp', null);
255+
expect(err).to.be.instanceOf(Error);
256+
expect(err).to.have.property('message', '"exp" should be a number of seconds');
263257
});
264258
});
265259
});

test/claim-iat.test.js

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -110,27 +110,6 @@ describe('issue at', function() {
110110
expectedIssueAt: 100,
111111
options: {}
112112
},
113-
// TODO an iat of -Infinity should fail validation
114-
{
115-
description: 'should set null "iat" when given -Infinity',
116-
iat: -Infinity,
117-
expectedIssueAt: null,
118-
options: {}
119-
},
120-
// TODO an iat of Infinity should fail validation
121-
{
122-
description: 'should set null "iat" when given Infinity',
123-
iat: Infinity,
124-
expectedIssueAt: null,
125-
options: {}
126-
},
127-
// TODO an iat of NaN should fail validation
128-
{
129-
description: 'should set to current time for "iat" when given value NaN',
130-
iat: NaN,
131-
expectedIssueAt: 60,
132-
options: {}
133-
},
134113
{
135114
description: 'should remove default "iat" with "noTimestamp" option',
136115
iat: undefined,
@@ -153,6 +132,21 @@ describe('issue at', function() {
153132
});
154133
});
155134
});
135+
136+
[
137+
-Infinity,
138+
Infinity,
139+
NaN,
140+
].forEach((iat) => {
141+
it(`should error when "iat" is ${util.inspect(iat)}`, function (done) {
142+
signWithIssueAt(iat, {}, (err) => {
143+
testUtils.asyncCheck(done, () => {
144+
expect(err).to.be.instanceOf(Error);
145+
expect(err.message).to.equal('"iat" should be a number of seconds');
146+
});
147+
});
148+
});
149+
});
156150
});
157151

158152
describe('when verifying a token', function() {

test/claim-nbf.test.js

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -228,35 +228,13 @@ describe('not before', function() {
228228
});
229229
});
230230

231-
// TODO an nbf of -Infinity should fail validation
232-
it('should set null "nbf" when given -Infinity', function (done) {
233-
signWithNotBefore(undefined, {nbf: -Infinity}, (err, token) => {
234-
const decoded = jwt.decode(token);
235-
testUtils.asyncCheck(done, () => {
236-
expect(err).to.be.null;
237-
expect(decoded).to.have.property('nbf', null);
238-
});
239-
});
240-
});
241-
242-
// TODO an nbf of Infinity should fail validation
243-
it('should set null "nbf" when given value Infinity', function (done) {
244-
signWithNotBefore(undefined, {nbf: Infinity}, (err, token) => {
245-
const decoded = jwt.decode(token);
246-
testUtils.asyncCheck(done, () => {
247-
expect(err).to.be.null;
248-
expect(decoded).to.have.property('nbf', null);
249-
});
250-
});
251-
});
252-
253-
// TODO an nbf of NaN should fail validation
254-
it('should set null "nbf" when given value NaN', function (done) {
255-
signWithNotBefore(undefined, {nbf: NaN}, (err, token) => {
256-
const decoded = jwt.decode(token);
257-
testUtils.asyncCheck(done, () => {
258-
expect(err).to.be.null;
259-
expect(decoded).to.have.property('nbf', null);
231+
[-Infinity, Infinity, NaN].forEach((nbf) => {
232+
it(`should error when "nbf" is ${util.inspect(nbf)}`, function (done) {
233+
signWithNotBefore(undefined, {nbf}, (err) => {
234+
testUtils.asyncCheck(done, () => {
235+
expect(err).to.be.instanceOf(Error);
236+
expect(err).to.have.property('message', '"nbf" should be a number of seconds');
237+
});
260238
});
261239
});
262240
});

0 commit comments

Comments
 (0)