Skip to content

Commit

Permalink
Merge pull request #41 from tj/nvw-unsign-fixes
Browse files Browse the repository at this point in the history
Avoid accepting otherwise-valid cookies when they have extra garbage appended
  • Loading branch information
natevw authored Feb 17, 2022
2 parents 025a9f3 + ea03dd5 commit 58727f3
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 12 deletions.
23 changes: 12 additions & 11 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,24 @@ exports.sign = function(val, secret){
};

/**
* Unsign and decode the given `val` with `secret`,
* Unsign and decode the given `input` with `secret`,
* returning `false` if the signature is invalid.
*
* @param {String} val
* @param {String} input
* @param {String} secret
* @return {String|Boolean}
* @api private
*/

exports.unsign = function(val, secret){
if ('string' != typeof val) throw new TypeError("Signed cookie string must be provided.");
exports.unsign = function(input, secret){
if ('string' != typeof input) throw new TypeError("Signed cookie string must be provided.");
if ('string' != typeof secret) throw new TypeError("Secret string must be provided.");
var str = val.slice(0, val.lastIndexOf('.'))
, mac = exports.sign(str, secret)
, macBuffer = Buffer.from(mac)
, valBuffer = Buffer.alloc(macBuffer.length);

valBuffer.write(val);
return crypto.timingSafeEqual(macBuffer, valBuffer) ? str : false;
var tentativeValue = input.slice(0, input.lastIndexOf('.')),
expectedInput = exports.sign(tentativeValue, secret),
expectedBuffer = Buffer.from(expectedInput),
inputBuffer = Buffer.from(input);
return (
expectedBuffer.length === inputBuffer.length &&
crypto.timingSafeEqual(expectedBuffer, inputBuffer)
) ? tentativeValue : false;
};
12 changes: 11 additions & 1 deletion test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ describe('.unsign(val, secret)', function(){
it('should unsign the cookie', function(){
var val = cookie.sign('hello', 'tobiiscool');
cookie.unsign(val, 'tobiiscool').should.equal('hello');
cookie.unsign(val, 'luna').should.be.false;
cookie.unsign(val, 'luna').should.be.false();
})
it('should reject malformed cookies', function(){
var pwd = 'actual sekrit password';
cookie.unsign('fake unsigned data', pwd).should.be.false();

var val = cookie.sign('real data', pwd);
cookie.unsign('garbage'+val, pwd).should.be.false();
cookie.unsign('garbage.'+val, pwd).should.be.false();
cookie.unsign(val+'.garbage', pwd).should.be.false();
cookie.unsign(val+'garbage', pwd).should.be.false();
})
})

0 comments on commit 58727f3

Please sign in to comment.