# Deserialization attack prevention

- **Pattern:** `ab-002413` (`security-hardening.secrets-config.deserialization`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002413
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002413)

## Why it matters

Unsafe deserialization (CWE-502, OWASP A08 Software and Data Integrity Failures) enables remote code execution when attacker-controlled serialized objects are reconstructed by a library that executes code during deserialization. The `node-serialize` library is the canonical Node.js example: it evaluates immediately-invoked function expressions (IIFEs) embedded in the serialized payload. NIST 800-53 SI-10 requires validation of all input before processing. Unlike JSON.parse (which only creates primitive values and plain objects), unsafe deserialization libraries can reconstruct class instances, triggering constructor side effects defined by the attacker.

## Severity rationale

Low because exploiting unsafe deserialization requires a specific vulnerable library to be used on attacker-controlled input, but successful exploitation achieves arbitrary code execution.

## Remediation

Replace unsafe deserialization libraries with `JSON.parse` followed by Zod schema validation. Never call `node-serialize.unserialize()` on untrusted input:

```ts
import { z } from 'zod'

// Unsafe — executes IIFEs in the payload:
// const data = require('node-serialize').unserialize(userInput)

// Safe — only parses JSON primitives, then validates shape:
const DataSchema = z.object({
  type: z.enum(['config', 'preferences']),
  value: z.number().int().nonnegative(),
})

const parsed = JSON.parse(userInput)  // No code execution
const data = DataSchema.parse(parsed) // Throws on invalid shape
```

Audit `package.json` for `node-serialize`, `serialize-javascript` (when used to deserialize), or `qs` with `allowPrototypes: true` — these are the most commonly exploited deserialization vectors in Node.js.

## Detection

- **ID:** `deserialization`
- **Severity:** `low`
- **What to look for:** List all deserialization points where external data is parsed (JSON.parse with eval, pickle, yaml.load, unserialize). For each, search for deserialization of untrusted data: `eval()`, `JSON.parse()` of user data without schema validation, `node-serialize`, `serialize-javascript` usage for untrusted data. The most dangerous patterns involve deserialization libraries that execute code during the deserialization process.
- **Pass criteria:** JSON.parse is used (not eval) for JSON data, followed by schema validation. No deserialization libraries that support arbitrary code execution (node-serialize, serialized-object) process untrusted input — 100% of deserialization must use safe methods (no eval, no unsafe load). Report: "X deserialization points found, all Y use safe parsing methods."
- **Fail criteria:** User-provided serialized data is deserialized using a library that supports arbitrary code execution during deserialization (e.g., `node-serialize.unserialize(userInput)`).
- **Skip (N/A) when:** The application does not deserialize any user-provided serialized objects (JSON with schema validation is fine).
- **Detail on fail:** `"node-serialize.unserialize() called on user-provided data in lib/session.ts — IIFE execution during deserialization possible"` or `"eval() used to parse user-submitted configuration data"`
- **Remediation:** Use JSON with schema validation only — never deserialize objects that can reconstruct class instances from untrusted input:

  ```ts
  // Bad: executes code during deserialization
  const data = require('node-serialize').unserialize(userInput)

  // Good: JSON.parse + schema validation
  import { z } from 'zod'
  const DataSchema = z.object({ type: z.string(), value: z.number() })

  const parsed = JSON.parse(userInput)           // Only parses, no code execution
  const data = DataSchema.parse(parsed)          // Validates types and shape
  ```

---

## External references

- cwe CWE-502
- owasp A08
- nist SI-10

Taxons: injection-and-input-trust

HTML version: https://auditbuffet.com/patterns/ab-002413
