diff --git a/package.json b/package.json index 0fae1f6b..c4431e12 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,9 @@ "lib": "lib", "test": "test" }, - "dependencies": {}, + "dependencies": { + "buffer-equal-constant-time": "^1.0.1" + }, "devDependencies": { "axios": "^0.17.1", "coveralls": "^3.0.0", diff --git a/verify/index.js b/verify/index.js index 8a9316b9..888a1979 100644 --- a/verify/index.js +++ b/verify/index.js @@ -1,7 +1,10 @@ module.exports = verify +const crypto = require('crypto') const Buffer = require('buffer').Buffer +const timingSafeEqualPolyfill = require('buffer-equal-constant-time') + const sign = require('../sign') function verify (secret, eventPayload, signature) { @@ -9,8 +12,23 @@ function verify (secret, eventPayload, signature) { throw new TypeError('secret, eventPayload & signature required') } - return Buffer.compare( - Buffer.from(signature), - Buffer.from(sign(secret, eventPayload)) - ) === 0 + const signatureBuffer = Buffer.from(signature) + const verificationBuffer = Buffer.from(sign(secret, eventPayload)) + + if (signatureBuffer.length !== verificationBuffer.length) { + return false + } + + return timingSafeEqual(signatureBuffer, verificationBuffer) +} + +/* istanbul ignore next */ +function timingSafeEqual (signatureBuffer, verificationBuffer) { + // crypto.verificationBuffer was added in Node 6.6 + // https://nodejs.org/docs/latest-v6.x/api/crypto.html#crypto_crypto_timingsafeequal_a_b + if ('timingSafeEqual' in crypto) { + return crypto.timingSafeEqual(signatureBuffer, verificationBuffer) + } + + return timingSafeEqualPolyfill(signatureBuffer, verificationBuffer) }