T09 · Insecure Skill Coding Practices
- Location
scripts/excavate.py:271- Finding
Arbitrary Code Execution Through Unsafe Pickle Index Deserialization
- Content
View full analysis
"ArchaeologyIndex": with open(path, "rb") as fh: data = pickle.load(fh) idx = cls() idx.docs = data.get("docs", []) return idx ``` The user-facing `query` command passes the supplied index file into this method: ```python idx = ArchaeologyIndex.load(args.index_file) ``` ### Technical Analysis Python's `pickle` format is capable of encoding instructions that invoke arbitrary Python callables during deserialization. Consequently, `pickle.load()` is not a data-only parser and must never process an index whose integrity and provenance are not guaranteed. The `query` subcommand accepts an arbitrary filesystem path, checks only that it refers to a file, and then deserializes it without authentication, integrity verification, type validation, or a trust warning. The documented `.idx` extension does not provide any protection. A malicious pickle can use a crafted reduction operation, such as an object implementing `__reduce__`, to invoke a command-execution callable while `pickle.load()` reconstructs the object. Execution occurs before `data.get("docs", [])` or any subsequent validation can run. This is not remote code execution by itself because the program does not download indexes. However, it becomes arbitrary local code execution whenever an attacker can convince a user or agent to query an attacker-provided index, replace an existing shared index, or modify an index in a writable location. ### Attack Path 1. An attacker constructs a malicious pickle whose deserialization routine invokes an arbitrary Python callable or operating-system command. 2. The attacker distributes it as a plausible archaeology index, such as `sessions.idx`, or replaces an index in a shared or attacker-wr ...[truncated 1121 chars]- Remediation
View remediation
