From penetration-tester
Scans source code for unsafe deserialization APIs like pickle, Marshal.load, readObject, unserialize, BinaryFormatter, and node-serialize. Use for pre-commit gates, audits, and incident reviews.
How this skill is triggered — by the user, by Claude, or both
Slash command
/penetration-tester:detecting-insecure-deserializationThis skill is limited to the following tools:
These tools are removed from Claude's available pool while this skill is active:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Insecure deserialization (CWE-502, OWASP A08:2021) is the highest-
Insecure deserialization (CWE-502, OWASP A08:2021) is the highest-
severity injection class in many language stacks because it directly
maps to RCE. Pickle, Java serialization, PHP unserialize, and
BinaryFormatter all execute object-construction code during
deserialization. If that code includes __reduce__ /
readObject / __wakeup / OnDeserialization callbacks that
the attacker controls, the deserialization step IS code execution.
Most legitimate use cases have safer alternatives (JSON for data, YAML with safe-load, Protocol Buffers, Avro). The remaining cases need explicit type allow-lists and HMAC-signed payloads.
| Finding | Severity | Threshold | Affected control |
|---|---|---|---|
Python pickle.loads(...) | CRITICAL | always (untrusted input) | CWE-502 |
Python pickle.load(file) | CRITICAL | always | CWE-502 |
Python dill.loads | CRITICAL | always | CWE-502 |
Python yaml.load(...) without Loader= | CRITICAL | unsafe legacy default | CWE-502 |
Python yaml.unsafe_load(...) | CRITICAL | explicit unsafe | CWE-502 |
Python shelve.open(...) | HIGH | pickle-backed; user-controllable filename | CWE-502 |
Java ObjectInputStream.readObject() | CRITICAL | always | CWE-502 |
PHP unserialize($input) | CRITICAL | non-literal input | CWE-502 |
.NET BinaryFormatter.Deserialize(...) | CRITICAL | deprecated unsafe API | CWE-502 |
.NET NetDataContractSerializer | CRITICAL | also unsafe | CWE-502 |
.NET LosFormatter.Deserialize | CRITICAL | ViewState path | CWE-502 |
Ruby Marshal.load(...) | CRITICAL | non-literal | CWE-502 |
Ruby YAML.load(...) (pre-3.1 Psych) | CRITICAL | safe in Psych 4.0+; needs version check | CWE-502 |
Node.js node-serialize.unserialize | CRITICAL | known-vulnerable lib | CWE-502 |
Node.js serialize-javascript reviver | HIGH | if used to deserialize untrusted | CWE-502 |
python3 ${CLAUDE_PLUGIN_ROOT}/skills/detecting-insecure-deserialization/scripts/scan_deserialization.py /path/to/repo
Options same as previous skills: --output, --format,
--min-severity, --include-tests, --languages.
CRITICAL across the board because these APIs grant RCE during deserialization if the input is attacker-controlled. The verification step is "can the input ever originate from untrusted source" — if yes, it's an immediate fix.
The fix depends on the data shape:
json.loads.See references/PLAYBOOK.md for per-language migrations.
python3 ${CLAUDE_PLUGIN_ROOT}/skills/detecting-insecure-deserialization/scripts/scan_deserialization.py \
/path/to/celery-workers --min-severity high
Celery defaults to pickle in older configurations; this finds the remaining unsafe-default callers.
- name: Deserialization scan
run: |
python3 plugins/security/penetration-tester/skills/detecting-insecure-deserialization/scripts/scan_deserialization.py \
. --min-severity high
JSON / JSONL / Markdown. Exit codes: 0 / 1 / 2.
Pickle / Marshal usage on a private cache file written by the same application is technically safe (the attacker can't influence the file contents). The scanner flags it as CRITICAL; verify by reading where the input file originates.
references/THEORY.md — Why deserialization is RCE, gadget chains,
HMAC-signing pattern, schema-validation alternativesreferences/PLAYBOOK.md — Per-language migrations (Python pickle
→ JSON / msgpack, yaml.load → yaml.safe_load, Java ObjectInputStream
→ JSON via Jackson with allow-list, PHP unserialize → JSON
alternatives, .NET BinaryFormatter → System.Text.Json)npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin penetration-testerAttack checklist for insecure deserialization in Java, PHP, .NET, Python. Covers sinks, ysoserial gadgets, magic methods, evasion. Use only for authorized security testing.
Analyzes insecure deserialization risks in Java, Python, PHP, Ruby, and .NET — focusing on RCE via ObjectInputStream, pickle, unserialize, Marshal.load, and YAML.load.
Prevents insecure deserialization vulnerabilities when processing data from untrusted sources (pickle, Java serialization, YAML, PHP unserialize). Recommends data-only formats and signed serialization.