Skip to content

Commit

Permalink
Handle signed cookies (#222)
Browse files Browse the repository at this point in the history
  • Loading branch information
JohanManders committed Apr 12, 2024
1 parent 49252b0 commit 854b84c
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 2 deletions.
13 changes: 11 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,17 @@ function fastifySecureSession (fastify, options, next) {
// the hooks must be registered after @fastify/cookie hooks

fastify.addHook('onRequest', (request, reply, next) => {
for (const [sessionName, { cookieName }] of sessionNames.entries()) {
const cookie = request.cookies[cookieName]
for (const [sessionName, { cookieName, cookieOptions }] of sessionNames.entries()) {
let cookie = request.cookies[cookieName]

if (cookie !== undefined && cookieOptions.signed === true) {
const unsignedCookie = fastify.unsignCookie(cookie)

if (unsignedCookie.valid === true) {
cookie = unsignedCookie.value
}
}

const result = fastify.decodeSecureSession(cookie, request.log, sessionName)

request[sessionName] = result || new Proxy(new Session({}), sessionProxyHandler)
Expand Down
94 changes: 94 additions & 0 deletions test/signed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
'use strict'

const tap = require('tap')
const fastify = require('fastify')({ logger: false })
const sodium = require('sodium-native')

tap.test('signed session cookie should works if not tampered with', function (t) {
const key = Buffer.alloc(sodium.crypto_secretbox_KEYBYTES)
sodium.randombytes_buf(key)

fastify.register(require('../'), {
key,
cookieName: '__Host-session',
cookie: {
secure: true,
httpOnly: true,
path: '/',
signed: true
}
})

fastify.post('/', (request, reply) => {
request.session.set('userId', '123')
reply.send('done')
})

t.teardown(fastify.close.bind(fastify))
t.plan(7)

fastify.get('/', (request, reply) => {
const data = request.session.get('userId')
if (!data) {
reply.code(404).send()
return
}
reply.send(data)
})

fastify.inject(
{
method: 'POST',
url: '/',
payload: {}
},
(error, response) => {
t.error(error)
t.equal(response.statusCode, 200)
t.ok(response.headers['set-cookie'])

const { name } = response.cookies[0]
t.equal(name, '__Host-session')

const originalCookie = response.headers['set-cookie']

fastify.inject(
{
method: 'GET',
url: '/',
headers: {
cookie: originalCookie
}
},
(error, response) => {
t.error(error)
t.same(response.payload, '123')
}
)

const cookieContent = originalCookie.split(';')[0]

// Change the last 5 characters to AAAAA, to tamper with the cookie
const cookieContentTampered = cookieContent.slice(0, -5) + 'AAAAA'

const tamperedCookie = originalCookie.replace(cookieContent, cookieContentTampered)

fastify.inject(
{
method: 'GET',
url: '/',
headers: {
cookie: tamperedCookie
}
},
(error, response) => {
if (error) {
t.fail('Unexpected error: ' + error.message)
} else {
t.equal(response.statusCode, 404, 'Should fail with tampered cookie')
}
}
)
}
)
})

0 comments on commit 854b84c

Please sign in to comment.