T09 · Insecure Skill Coding Practices
- Location
skill_doctor.py:274- Finding
Out-of-Scope File Read Through Symbolic Links
- Content
View full analysis
list[dict]: findings = [] for f in sorted(skill.path.rglob("*")): if not f.is_file() or f.suffix.lower() not in SCAN_SUFFIXES: continue if "node_modules" in f.parts or f.name.startswith("."): continue try: lines = f.read_text(encoding="utf-8", errors="replace").splitlines() except Exception: continue for n, line in enumerate(lines, 1): if len(line) > 1000: line = line[:1000] for pat, sev, why in SECURITY_RULES: if pat.search(line): findings.append( { "severity": sev, "file": str(f.relative_to(skill.path)), "line": n, "why": why, "snippet": line.strip()[:140], } ) ``` ### Technical Analysis The security scanner recursively enumerates entries under an installed skill directory and reads each entry that passes the filename-suffix checks. It does not reject symbolic links or verify that the resolved target remains within the scanned skill directory. Python's `Path.is_file()` and `Path.read_text()` follow symbolic links. Consequently, an untrusted installed skill can contain a file-shaped symbolic link whose name has an accepted suffix, such as `.py`, `.md`, or `.sh`, while its target is an arbitrary file outside the skill directory. If a line in the external target matches a rule in `SECURITY_RULES`, up to 140 characters of that line are copied into the generated report. This is particularly relevant because the rules deliberately m ...[truncated 2324 chars]- Remediation
View remediation
