T09 · Insecure Skill Coding Practices
- Location
scripts/indexer.py:498- Finding
Unsafe Deserialization of a Repository-Controlled Pickle Cache
- Content
View full analysis
Vulnerability Details
File Location:
scripts/indexer.py, lines 498–499
Vulnerability Type: Unsafe Python pickle deserialization
Risk Level: HighVulnerable Code
python if self.cache_file.exists(): with open(self.cache_file, 'rb') as f: return pickle.load(f)The cache path is established under the analyzed project in
scripts/indexer.py, lines 124–129:python def _get_default_cache_dir(self) -> Path: """Get default cache directory""" # Store cache in project's .codebase-intelligence directory cache_dir = self.root / '.codebase-intelligence' cache_dir.mkdir(exist_ok=True) return cache_dirTechnical Analysis
Python pickle data is executable serialization rather than a safe data-only format. During
pickle.load(), specially crafted objects can invoke attacker-selected callables through pickle reduction operations.The default cache file is
<analyzed-project>/.codebase-intelligence/codebase_index.pkl. Because the Skill is designed to inspect arbitrary projects, that file may be supplied by an untrusted repository author. The implementation checks only whether the file exists; it does not verify its origin, integrity, signature, ownership, or expected schema before deserializing it.Indexer.build_index()attempts to load this cache before rebuilding the index. The same vulnerable behavior is therefore reachable through documented operations that build or access an index, including theanalyze,ask, andindexcommands.Catching exceptions around deserialization does not mitigate this issue because a malicious reduction callable can execute before
pickle.load()returns or raises an error.Attack Path
- An attacker creates a malicious pickle whose deserialization reduction invokes an arbitrary Python callable, such as a process-launching or file-writing function.
- The attacker places it at
.codebase-intelligence/codebase_index.pklin a repository. - A victim clones ...[truncated 1138 chars]
- Remediation
View remediation
Remediation Suggestions
- Remove pickle from the cache format. Use a data-only format such as JSON, which the project already writes, and reconstruct
CodebaseIndexandFileIndexobjects after validation. - Validate the complete cache schema. Enforce expected field names, primitive types, path constraints, collection size limits, and cache-version compatibility before accepting cached data.
- Keep trusted cache state outside analyzed repositories. Store caches in a user-controlled cache directory and key each entry using a canonical project path or repository identifier. This reduces exposure to files committed by repository authors.
- Authenticate caches if non-JSON serialization is unavoidable. Verify a keyed MAC or digital signature before parsing. Authentication keys must not be stored in the analyzed repository.
- Never use
pickle.load()on untrusted or repository-controlled files. Restricted unpicklers and exception handling are not reliable substitutes for a non-executable serialization format. - Harden file handling. Reject symbolic-link cache files, verify ownership and permissions where supported, use restrictive permissions, and write updates atomically through a safely created temporary file followed by replacement.
- Invalidate legacy caches. After deploying the fix, ignore or delete existing
.pklcaches without deserializing them and rebuild the index from source files.
- Remove pickle from the cache format. Use a data-only format such as JSON, which the project already writes, and reconstruct
