← All fixes

Fix it

Insecure deserialization (pickle) — how to fix it

High severityCWE-502 (Deserialization of Untrusted Data)

Python's pickle can reconstruct arbitrary objects, and loading a pickle from an untrusted source runs code during that process. If the data came from a user, a file upload, a cache, or a queue an attacker can reach, pickle.loads is remote code execution. Use a data-only format like JSON instead.

Why it's a problem

A crafted pickle payload executes code the moment it is loaded, with your process's privileges, before you ever inspect the result. Because pickle is often used for caching and message passing, the untrusted input can arrive somewhere that does not look like user input at all, which is why this is so easy to miss.

The pattern

import pickle
# runs code embedded in the payload
obj = pickle.loads(request.data)

The fix

import json
# JSON only carries data, never code
obj = json.loads(request.data)

Why AI tools write this

pickle is the shortest way to round-trip a Python object, so when a task involves caching or passing objects between processes it is a natural completion. It works perfectly with your own trusted data, and becomes code execution only when the source is attacker-controlled.

The quick fix

  • Use JSON or another data-only format for anything that crosses a trust boundary.
  • Never unpickle data from a user, an upload, or a shared cache or queue.
  • If you must use pickle, restrict it to data your own process produced and stored securely.

Want to know if this pattern is already in a repo you shipped? Scan a public repo free, no account needed.

Scan a repo →
Insecure Deserialization (pickle.loads) — How to Fix It: Prbl