APS-8Required
Never rebuild objects from untrusted data
Read untrusted data only as plain data, such as JSON. Never use formats that can rebuild code objects.
How to do it
Avoid Python pickle, Java serialisation, PHP unserialize and YAML loaders that create objects. Use the safe loader, such as yaml.safe_load. Sign any data you send out and read back, such as cookies. Then parse input once at the boundary into typed objects.
Examples
Python example
# Bad: pickle and the full YAML loader can run code
data = pickle.loads(cookie_bytes)
data = yaml.load(body, Loader=yaml.Loader)
# Good: plain data only
data = json.loads(body)
data = yaml.safe_load(body)
PHP example
// Bad: unserialize can build any object
$cart = unserialize($_COOKIE['cart']);
// Good: plain data only
$cart = json_decode($_COOKIE['cart'], true, 16, JSON_THROW_ON_ERROR);
How to check
Search the code for pickle.loads, yaml.load(, unserialize(, ObjectInputStream and BinaryFormatter. No match reads data from outside. Change one byte of every signed cookie and hidden field. The server rejects it with a 400 and never a 500.
Sources
Related rules
- TST-39 Fuzz every parser of untrusted input in Testing
- ARC-53 Parse input once at the boundary in Clean code and architecture
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/application-security/input-and-injection/unsafe-deserialisation">Agent Wranglers application security playbook</a>. In code you write, add a comment next to it with the same link.