High severity7.4NVD Advisory· Published May 21, 2024· Updated Apr 15, 2026
CVE-2024-35220
CVE-2024-35220
Description
@fastify/session is a session plugin for fastify. Requires the @fastify/cookie plugin. When restoring the cookie from the session store, the expires field is overriden if the maxAge field was set. This means a cookie is never correctly detected as expired and thus expired sessions are not destroyed. This vulnerability has been patched 10.8.0.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
@fastify/sessionnpm | < 10.9.0 | 10.9.0 |
Patches
10495ce5b534cMerge pull request from GHSA-pj27-2xvp-4qxg
3 files changed · +71 −1
lib/cookie.js+5 −0 modified@@ -11,6 +11,10 @@ module.exports = class Cookie { this.partitioned = cookie.partitioned this._expires = null + if(cookie.expires) { + this.originalExpires = new Date(cookie.expires) + } + if (originalMaxAge) { this.maxAge = originalMaxAge } else if (cookie.expires) { @@ -56,6 +60,7 @@ module.exports = class Cookie { return { expires: this._expires, originalMaxAge: this.originalMaxAge, + originalExpires: this.originalExpires, sameSite: this.sameSite, secure: this.secure, path: this.path,
lib/fastifySession.js+3 −1 modified@@ -92,7 +92,9 @@ function fastifySession (fastify, options, next) { decryptedSessionId ) - if (restoredSession.cookie.expires && restoredSession.cookie.expires.getTime() <= Date.now()) { + const expiration = restoredSession.cookie.originalExpires || restoredSession.cookie.expires + + if (expiration && expiration.getTime() <= Date.now()) { restoredSession.destroy(err => { if (err) { done(err)
test/expiration.test.js+63 −0 added@@ -0,0 +1,63 @@ +"use strict"; + +const test = require("tap").test; +const { buildFastify, DEFAULT_SECRET } = require("./util"); +const { setTimeout } = require("node:timers/promises"); + +test("sessions should be deleted if expired", async (t) => { + t.plan(5); + + const sessions = {}; + const options = { + secret: DEFAULT_SECRET, + store: { + get(id, cb) { + t.pass("session was restored"); + cb(null, sessions[id]); + }, + set(id, session, cb) { + sessions[id] = session; + cb(); + }, + destroy(id, cb) { + t.pass("expired session is destroyed"); + cb(); + }, + }, + cookie: { maxAge: 1000, secure: false }, + }; + + const fastify = await buildFastify((request, reply) => { + reply.send(200); + }, options); + t.teardown(() => { + fastify.close(); + }); + + let response; + response = await fastify.inject({ + url: "/", + }); + + const initialSession = response.headers["set-cookie"] + .split(" ")[0] + .replace(";", ""); + t.ok(initialSession.startsWith("sessionId=")); + + // Wait for the cookie to expire + await setTimeout(2000); + + response = await fastify.inject({ + url: "/", + headers: { + Cookie: initialSession, + }, + }); + + const endingSession = response.headers["set-cookie"] + .split(" ")[0] + .replace(";", ""); + t.ok(endingSession.startsWith("sessionId=")); + + t.not(initialSession, endingSession); +});
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5News mentions
0No linked articles in our index yet.