Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,11 @@ function JSONCookies (obj) {
key = cookies[i]
val = JSONCookie(obj[key])

if (val) {
// Boolean false is reserved: signedCookies() uses it to mark a cookie whose
// signature did not verify, so writing a parsed "j:false" here would make an
// authentic value indistinguishable from a tampered one (#168). Left as the
// raw string until that representation is settled.
if (val !== undefined && val !== false) {
obj[key] = val
}
}
Expand Down
35 changes: 35 additions & 0 deletions test/cookieParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,23 @@ describe('cookieParser()', function () {
.expect(200, '{"foo":"foobarbaz"}', done)
})

it('should keep an authentic JSON false distinct from a tampered cookie', function (done) {
var signed = signature.sign('j:false', 'keyboard cat')
request(createServer('keyboard cat'))
.get('/signed')
.set('Cookie', 'flag=s:' + signed)
.expect(200, '{"flag":"j:false"}', done)
})

it('should report a tampered cookie as false', function (done) {
var signed = signature.sign('j:false', 'keyboard cat')
var tampered = signed.slice(0, -1) + (signed.slice(-1) === 'a' ? 'b' : 'a')
request(createServer('keyboard cat'))
.get('/signed')
.set('Cookie', 'flag=s:' + tampered)
.expect(200, '{"flag":false}', done)
})

it('should remove the signed value from req.cookies', function (done) {
request(createServer('keyboard cat'))
.get('/')
Expand Down Expand Up @@ -162,6 +179,24 @@ describe('cookieParser.JSONCookie(str)', function () {
})
})

describe('cookieParser.JSONCookies(obj)', function () {
it('should parse falsy JSON cookie values', function () {
assert.deepEqual(cookieParser.JSONCookies({
z: 'j:0',
e: 'j:""',
n: 'j:null'
}), { z: 0, e: '', n: null })
})

it('should leave a JSON false as its raw string, so it stays distinct from the signature-failure marker', function () {
assert.deepEqual(cookieParser.JSONCookies({ f: 'j:false' }), { f: 'j:false' })
})

it('should leave non-JSON cookie values untouched', function () {
assert.deepEqual(cookieParser.JSONCookies({ a: 'bar', b: 'j:{foo:"bar"}' }), { a: 'bar', b: 'j:{foo:"bar"}' })
})
})

describe('cookieParser.signedCookie(str, secret)', function () {
it('should return undefined for non-string arguments', function () {
assert.strictEqual(cookieParser.signedCookie(undefined, 'keyboard cat'), undefined)
Expand Down