From 07972312ed11078af009e12adc1bea41e30f4797 Mon Sep 17 00:00:00 2001 From: Nazar Gargol Date: Tue, 22 Sep 2020 15:31:15 +1200 Subject: [PATCH] Extended resetToken.compare return result with reason for comparison failure refs https://github.com/TryGhost/Ghost/issues/11878 - To be able to identify the reason behind comparison failure on more granular level (like token expiration) had to provide additional information in return result for falsy token comparisons --- ghost/security/lib/tokens.js | 20 +++++++++++++++++--- ghost/security/test/tokens.test.js | 14 +++++++++----- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/ghost/security/lib/tokens.js b/ghost/security/lib/tokens.js index 973c853d80..9614d06fe0 100644 --- a/ghost/security/lib/tokens.js +++ b/ghost/security/lib/tokens.js @@ -87,12 +87,18 @@ module.exports.resetToken = { let i; if (isNaN(parts.expires)) { - return false; + return { + correct: false, + reason: 'invalid_expiry' + }; } // Check if token is expired to prevent replay attacks if (parts.expires < Date.now()) { - return false; + return { + correct: false, + reason: 'expired' + }; } generatedToken = exports.resetToken.generateHash({ @@ -110,6 +116,14 @@ module.exports.resetToken = { diff |= tokenToCompare.charCodeAt(i) ^ generatedToken.charCodeAt(i); } - return diff === 0; + const result = { + correct: (diff === 0) + }; + + if (!result.correct) { + result.reason = 'invalid'; + } + + return result; } }; diff --git a/ghost/security/test/tokens.test.js b/ghost/security/test/tokens.test.js index 7947297407..adfbf01287 100644 --- a/ghost/security/test/tokens.test.js +++ b/ghost/security/test/tokens.test.js @@ -39,7 +39,8 @@ describe('Utils: tokens', function () { password: '12345678' }); - tokenIsCorrect.should.eql(true); + tokenIsCorrect.correct.should.eql(true); + should(tokenIsCorrect.reason).be.undefined; }); it('compare: error from invalid password', function () { @@ -61,7 +62,8 @@ describe('Utils: tokens', function () { password: '123456' }); - tokenIsCorrect.should.eql(false); + tokenIsCorrect.correct.should.eql(false); + tokenIsCorrect.reason.should.eql('invalid'); }); it('compare: error from invalid expires parameter', function () { @@ -83,7 +85,8 @@ describe('Utils: tokens', function () { password: '123456' }); - tokenIsCorrect.should.eql(false); + tokenIsCorrect.correct.should.eql(false); + tokenIsCorrect.reason.should.eql('invalid_expiry'); }); it('compare: error from expired token', function () { @@ -105,7 +108,8 @@ describe('Utils: tokens', function () { password: '123456' }); - tokenIsCorrect.should.eql(false); + tokenIsCorrect.correct.should.eql(false); + tokenIsCorrect.reason.should.eql('expired'); }); it('extract', function () { @@ -189,7 +193,7 @@ describe('Utils: tokens', function () { password: '12345678' }); - tokenIsCorrect.should.eql(true); + tokenIsCorrect.correct.should.eql(true); }); });