# LlamaIndex Object Node Mapping Pickle Deserialization

- **Severity:** High
- **Signature ID:** `3f6b1c92-4d7a-4a11-9e3c-8b5d0a2f7c64`

## Summary

LlamaIndex stores certain indexes using Python's pickle format, which can run arbitrary code when loaded. This rule flags command lines that combine a pickle-loading call with either LlamaIndex's object-mapping code or a known code-execution payload, catching attempts to exploit this weakness.

## How the attack works

LlamaIndex's SimpleObjectNodeMapping/ObjectIndex persistence used Python's pickle to save and restore objects. An attacker crafts a pickle payload containing a malicious object (using tricks like __reduce__, os.system, or subprocess calls) that runs code the moment it is unpickled. They then get that payload loaded, either through LlamaIndex's own object-mapping code path or via an inline Python command that decodes and unpickles a base64-encoded payload. The vulnerability was fixed in version 0.14.16 with a RestrictedUnpickler that blocks dangerous classes.

## Why it matters

If exploited, an attacker can achieve arbitrary code execution on the system hosting the LlamaIndex application, potentially leading to full compromise of the host, data theft, or further lateral movement.

## What you can do

- Upgrade llama_index to 0.14.16 or later, which restricts unsafe unpickling.
- Avoid loading LlamaIndex object indexes or node mappings from untrusted or externally supplied sources.
- Review any code paths that persist or restore ObjectIndex/SimpleObjectNodeMapping data and replace pickle-based storage with a safer serialization format if possible.
- Monitor process command lines for combinations of pickle/dill/cloudpickle loading calls with LlamaIndex references or known RCE gadget patterns (os.system, subprocess, eval/exec).

## Known benign look-alikes

- Security engineer or AI agent grepping the llama_index source tree for the vulnerable call site (e.g. `git grep -n "pickle.loads" -- llama_index/`) -- suppressed by filter_source_search.
- SCA / SAST tooling whose command line embeds the vulnerable pattern as a query (e.g. `semgrep --pattern 'pickle.loads(...)'`, `pip-audit`, `osv-scanner`) -- suppressed by filter_sast.
- Regression tests for the RestrictedUnpickler fix, which legitimately construct pickle payloads next to SimpleObjectNodeMapping (e.g. `pytest -k test_object_node_mapping`) -- suppressed by filter_test_runner.
- Remediation commands such as `pip install --upgrade "llama-index>=0.14.16"` -- suppressed by filter_pkg_mgmt (and would not match sel_deser_api anyway).
- Legitimate ML pipelines that load a persisted llama_index ObjectIndex via `from_persist_dir(...)` -- does NOT fire, because sel_llama_ctx alone is never sufficient; an explicit unpickling primitive or an inline pickle blob must also be present on the same command line.
- Data-science one-liners that unpickle a trusted local artifact (`python -c "import pickle;pickle.load(open('model.pkl','rb'))"`) -- does NOT fire, because neither llama_index context nor an RCE gadget nor an inline serialized payload is present.

## References

- https://cwe.mitre.org/data/definitions/502.html
- https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures/
- https://docs.python.org/3/library/pickle.html#restricting-globals

---
Source: https://www.netzilo.com/threats/llamaindex-pickle-deserialization
