The Session Cookie That Ran eval()
node-serialize unserialize() executes the payload it is given
Published Oct 29, 2026
Executive Summary
A vibe-coded Express app stores the session in a signed cookie and restores it with node-serialize's unserialize() — a function built on eval(). A crafted cookie payload (the _$$ND_FUNC$$_ marker) executes arbitrary JavaScript on the server. The session round-trip is an eval endpoint in disguise.
The Prompt
“Store the user's session object in a signed cookie and restore it on each request.”
The Flaw
node-serialize's unserialize() reconstructs objects by evaluating JavaScript. A payload with the _$$ND_FUNC$$_ marker turns the cookie into a function call — so a crafted cookie executes arbitrary code as the server process. The 'signed cookie' gives a false sense of safety: signing proves the cookie is unchanged, not that it is safe to eval.
Risk & Impact
[Security] Any visitor can forge a cookie that runs code on the server. The session feature is an open eval endpoint, signature or not.
Cost: Remote code execution and full server compromise from a single forged cookie.
Code Comparison
❌ Vulnerable (AI generated)
❌ Vulnerable (AI generated)
✅ Hardened (production ready)
The Fix
Use a data-only format — JSON plus a signed token (JWT) or a server-side session store. Never eval() serialized bytes, and never deserialize client-supplied objects.
Prevention
- [linter] Ban node-serialize and any eval/new Function on request data in ESLint security rules.
- [ci] A test that feeds the known _$$ND_FUNC$$_ payload must be rejected, never executed.
- [manual] Forbid eval-based serializers (rule 6) and require server-side sessions or signed JSON (rule 3).
Why This Happened
Root cause: the prompt omitted Rule 3 and Rule 6 — the guardrails that would have caught this. See the full guide →
