From 5120a076d0b5b24b9ebd0dcdb8b40d4dfcd535a3 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Thu, 13 Jan 2022 22:55:43 +0100 Subject: [PATCH] fix: passing null as checks.nonce should not disable it --- lib/client.js | 10 +++++--- test/client/client_instance.test.js | 39 ++++++++++++++++------------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/lib/client.js b/lib/client.js index f006edac..a6c82954 100644 --- a/lib/client.js +++ b/lib/client.js @@ -37,6 +37,8 @@ const [major, minor] = process.version const rsaPssParams = major >= 17 || (major === 16 && minor >= 9); const retryAttempt = Symbol(); +const skipNonceCheck = Symbol(); +const skipMaxAgeCheck = Symbol(); function pickCb(input) { return pick( @@ -762,7 +764,7 @@ class BaseClient { const timestamp = now(); const { protected: header, payload, key } = await this.validateJWT(idToken, expectedAlg); - if (maxAge || (maxAge !== null && this.require_auth_time)) { + if (typeof maxAge === 'number' || (maxAge !== skipMaxAgeCheck && this.require_auth_time)) { if (!payload.auth_time) { throw new RPError({ message: 'missing required JWT property auth_time', @@ -777,7 +779,7 @@ class BaseClient { } } - if (maxAge && payload.auth_time + maxAge < timestamp - this[CLOCK_TOLERANCE]) { + if (typeof maxAge === 'number' && payload.auth_time + maxAge < timestamp - this[CLOCK_TOLERANCE]) { throw new RPError({ printf: [ 'too much time has elapsed since the last End-User authentication, max_age %i, auth_time: %i, now %i', @@ -792,7 +794,7 @@ class BaseClient { }); } - if (nonce !== null && (payload.nonce || nonce !== undefined) && payload.nonce !== nonce) { + if (nonce !== skipNonceCheck && (payload.nonce || nonce !== undefined) && payload.nonce !== nonce) { throw new RPError({ printf: ['nonce mismatch, expected %s, got: %s', nonce, payload.nonce], jwt: idToken, @@ -1090,7 +1092,7 @@ class BaseClient { if (tokenset.id_token) { await this.decryptIdToken(tokenset); - await this.validateIdToken(tokenset, null, 'token', null); + await this.validateIdToken(tokenset, skipNonceCheck, 'token', skipMaxAgeCheck); if (refreshToken instanceof TokenSet && refreshToken.id_token) { const expectedSub = refreshToken.claims().sub; diff --git a/test/client/client_instance.test.js b/test/client/client_instance.test.js index 5791ac7c..e011eec5 100644 --- a/test/client/client_instance.test.js +++ b/test/client/client_instance.test.js @@ -3017,7 +3017,7 @@ describe('Client', () => { }; return this.IdToken(this.keystore.get(), 'RS256', payload).then((token) => - this.client.validateIdToken(token, null, null, 300), + this.client.validateIdToken(token, undefined, null, 300), ); }); @@ -3054,7 +3054,7 @@ describe('Client', () => { }; return this.IdToken(this.keystore.get(), 'RS256', payload).then((token) => - this.client.validateIdToken(token, null, null, 300), + this.client.validateIdToken(token, undefined, null, 300), ); }); @@ -3078,24 +3078,27 @@ describe('Client', () => { }); }); - it('ignores auth_time presence check when require_auth_time is true but null is passed', function () { - const client = new this.issuer.Client({ - client_id: 'with-require_auth_time', - require_auth_time: true, - }); + // const {skipMaxAgeCheck} = require('../../lib/client') + // console.log(skipMaxAgeCheck) - const payload = { - iss: this.issuer.issuer, - sub: 'userId', - aud: client.client_id, - exp: now() + 3600, - iat: now(), - }; + // it.only('ignores auth_time presence check when require_auth_time is true but the private symbol is passed', function () { + // const client = new this.issuer.Client({ + // client_id: 'with-require_auth_time', + // require_auth_time: true, + // }); - return this.IdToken(this.keystore.get(), 'RS256', payload).then((token) => - client.validateIdToken(token, null, null, null), - ); - }); + // const payload = { + // iss: this.issuer.issuer, + // sub: 'userId', + // aud: client.client_id, + // exp: now() + 3600, + // iat: now(), + // }; + + // return this.IdToken(this.keystore.get(), 'RS256', payload).then((token) => + // client.validateIdToken(token, undefined, null, skipMaxAgeCheck), + // ); + // }); it('verifies auth_time is present when require_auth_time is true', function () { const client = new this.issuer.Client({