T09 · Insecure Skill Coding Practices
- Location
vet_scan.py:150- Finding
Symlink Traversal Allows Reading and Reporting Files Outside the Scan Target
- Content
View full analysis
Iterable[Path]: for path in sorted(root.rglob("*")): if not path.is_file(): continue rel = path.relative_to(root) if should_skip(rel): continue if path.name in DEFAULT_IGNORED_FILES: continue yield path ``` ```python def scan_file(path: Path, patterns: dict[str, list[re.Pattern[str]]]) -> dict[str, list[Match]]: try: content = path.read_text(encoding="utf-8", errors="replace").splitlines() except OSError: return {k: [] for k in patterns} ``` ```python "red_flags": { key: [m.__dict__ for m in matches[:20]] for key, matches in findings.items() }, ``` ### Technical Analysis The scanner recursively enumerates files beneath the supplied target with `Path.rglob()`. It verifies that each candidate is a file with `Path.is_file()`, but this operation follows symbolic links. The subsequent `Path.read_text()` operation also follows symbolic links. The lexical `path.relative_to(root)` check only confirms that the symlink entry is located under the target directory. It does not verify that the symlink's resolved destination remains under that directory. If an untrusted Skill package contains a symlink whose destination is a readable file elsewhere on the host, the scanner can read that external file. Any matching line is retained in the `Match.text` field. Up to 20 complete matches per category are then serialized into JSON output. Text and chat reports can also include a complete matched source line through `evidence_text()`. The scanner therefore exceeds the minimum privilege boundary implied by its command-line target: it can access readable files outside the directory t ...[truncated 1506 chars]- Remediation
View remediation
