T09 · Insecure Skill Coding Practices
- Location
scripts/run.py:48- Finding
Unrestricted Input and Output Paths Permit Workspace Escape
- Content
View full analysis
- Remediation
View remediation
Path: workspace_root = workspace.resolve(strict=True) relative = Path(raw_path) if relative.is_absolute(): raise ValueError(f"Absolute paths are not allowed: {raw_path}") candidate = (workspace_root / relative).resolve(strict=False) if not candidate.is_relative_to(workspace_root): raise ValueError(f"Path escapes workspace: {raw_path}") return candidate ``` 3. Apply the helper independently to every input and output: ```python packs_path = resolve_workspace_path(workspace, inputs[0]) bib_path = resolve_workspace_path(workspace, inputs[1]) out_path = resolve_workspace_path(workspace, outputs[0]) ``` 4. Restrict this exported Skill to its declared files where configurable paths are unnecessary: ```python packs_path = workspace / "outline/evidence_drafts.jsonl" bib_path = workspace / "citations/ref.bib" out_path = workspace / "outline/anchor_sheet.jsonl" ``` 5. Defend against symlink escapes. For existing inputs, resolve the complete path with `strict=True` and verify that it remains under the canonical workspace root. For outputs, validate the nearest existing parent after resolving symlinks, then open or replace the destination using APIs that prevent symlink following where supported. 6. Validate expected file types and names. Inputs should be regular files with the expected `.jsonl` and `.bib` extensions, and the output should be limited to the expected `.jsonl` location. 7. Perform the same validation in `tooling/executor.py` before forwarding paths from `UNITS.csv`. Validation in both the caller and callee provides defense in depth. 8. Add regression tests covering: - Relative paths wit ...[truncated 220 chars]
