SEC005-insecure-deser — Insecure Deserialization
Dimension: Security Default severity: High CWE: CWE-502 OWASP: A08:2021 – Software and Data Integrity Failures Languages: All (Python, JS/TS; Rust skipped — bincode/serde are not unsafe by default) Last reviewed: 2026-05-06
What it detects
Flags use of insecure deserialization APIs that can execute arbitrary code when fed untrusted input. Detection uses two complementary signals per file:
-
Import scan — at least one import path contains (case-insensitively) a known insecure-deser module substring:
Language Recognised import substrings Python pickle,cpickle,marshal,yamlJS/TS node-serialize,serialize-javascript -
Source scan — the raw file text is scanned for insecure call-site patterns:
pickle.load(,pickle.loads(cPickle.load(,cPickle.loads(marshal.load(,marshal.loads(yaml.load(— suppressed whenLoader=yaml.SafeLoader,Loader=SafeLoader, orLoader=yaml.CSafeLoaderappears within 120 bytesyaml.unsafe_load(unserialize(— only whennode-serializeis imported
If Signal 1 (import) is absent the file is skipped immediately. One finding is emitted per matching call site.
Why it matters
Deserializing untrusted data with pickle, marshal, or node-serialize allows an attacker to execute arbitrary code on the server. These formats embed executable Python/JS code directly in the serialized byte stream — loading a crafted payload is equivalent to running arbitrary code. OWASP A08:2021 lists insecure deserialization as a top-10 risk.
Configuration
This rule has no configurable threshold. Disable per project:
[rules.SEC005-insecure-deser]
enabled = false
Examples flagged
Python — pickle.loads on user-supplied data:
import pickle
def load_user_data(data: bytes):
return pickle.loads(data) # flagged: insecure deserialization
Python — yaml.load without a safe loader:
import yaml
def load_config(stream):
return yaml.load(stream) # flagged: yaml.load without safe Loader=
JS/TS — node-serialize.unserialize:
import serialize from "node-serialize";
export function loadData(data: string): unknown {
return serialize.unserialize(data); // flagged: insecure deserialization
}
Examples not flagged
Python — yaml.load with a safe loader:
import yaml
def load_config(stream):
return yaml.load(stream, Loader=yaml.SafeLoader) # not flagged
Python — json.loads (always safe):
import json
def load_data(s: str):
return json.loads(s) # not flagged
Fix guidance
- Python: replace
pickle.loadswithjson.loads; replaceyaml.loadwithyaml.safe_loador passLoader=yaml.SafeLoader. - JS/TS: replace
node-serialize.unserializewithJSON.parseon validated input. - Never deserialize data from untrusted sources using pickle, marshal, or node-serialize regardless of any other validation.
Implementation
- Source: crates/zuit-analyzers/src/insecure_deser.rs
- Severity / supported languages: see
RuleMetain source.