T09 · Insecure Skill Coding Practices
- Location
scripts/audit_case_rag.py:259- Finding
Path Traversal into Unsafe Joblib Deserialization
- Content
View full analysis
None: out_dir = Path(expand(args.out_dir)).resolve() idx_path = out_dir / f"{args.case}.joblib" if not idx_path.exists(): raise SystemExit(f"Index not found: {idx_path}. Run index first.") bundle = joblib.load(idx_path) ``` ### Technical Analysis The user-controlled `--case` value is interpolated directly into a file name without validating its format or confirming that the resulting path remains inside `out_dir`. A value containing traversal sequences such as `../../` can therefore resolve to a Joblib file outside the intended index directory. The selected file is subsequently passed to `joblib.load()`. Joblib uses Python's pickle-based serialization mechanism and must not be used with untrusted files because deserialization can invoke attacker-controlled Python callables. Merely loading a malicious Joblib file can consequently execute arbitrary code. This vulnerability is exploitable when an attacker can both: 1. Place or identify a malicious Joblib-compatible file readable by the victim; and 2. Influence the `--case` command-line argument used by the query operation. ### Attack Path 1. The attacker constructs a malicious Joblib or pickle-compatible object containing a deserialization payload. 2. The attacker places it at a location readable by the user running the skill, such as `/tmp/malicious.joblib`. 3. The query command is invoked with a traversal value, for example: ```bash python3 scripts/audit_case_rag.py query \ --out-dir /path/to/audit_rag_db \ --case ../../tmp/malicious \ "question" ``` 4. The constructed path escapes the configured output directory and targets the malicious file. 5. `joblib.load(idx_path)` deserializes the file. 6. The embedded payl ...[truncated 660 chars]- Remediation
View remediation
