Skip to content

SEC004 · Server module-scope state

Severity: warning · Category: security

Flags reassignment (=, +=, ??=, ++, …) of a module-scope let/var from inside a function in a SvelteKit route or hooks file (+page(.server).ts, +layout(.server).ts, +server.ts, hooks.server.ts). Reassignment directly from a request handler gets a stronger message than one in a helper function.

Not flagged: top-level initialisation, const bindings, and mutation-style caches (const cache = new Map() + cache.set(…)) — the latter is a deliberate memoisation pattern, though putting request-derived data in one carries the same risk. src/lib/server/** is not scanned (legitimate singletons live there). Assignments inside SvelteKit’s init hook are also not flagged — it runs once at server startup.

SvelteKit’s docs: “Avoid shared state on the server.” A module variable on the server is one instance shared by every user — if an action stores Alice’s form data there, Bob’s next request reads it. The value also silently resets whenever the process restarts.

+page.server.ts
let user; // ❌ one variable for every user of this server
export const actions = {
default: async ({ request, cookies, locals }) => {
const data = await request.formData();
user = { name: data.get('name') }; // ❌ NEVER DO THIS
await db.saveUser(locals.session, data); // ✅ per-user persistence
}
};

Authenticate with cookies/locals and persist per-user data to a database. For a deliberate process-wide cache, prefer a const container or add // svelte-vitals-disable-next-line SEC004 above the assignment.