T09 · Insecure Skill Coding Practices
- Location
scripts/skills_audit.py:106- Finding
Symlink Following Allows Out-of-Scope File Disclosure and Persistent Snapshot Capture
- Content
View full analysis
str | None: try: h = hashlib.sha256() with path.open("rb") as f: for chunk in iter(lambda: f.read(1024 * 1024), b""): h.update(chunk) return h.hexdigest() except Exception: return None ``` ```python def list_files(dir_path: Path) -> list[Path]: files: list[Path] = [] for p in dir_path.rglob("*"): if p.is_file(): if "/.git/" in str(p) or "/__pycache__/" in str(p): continue if p.suffix == ".pyc": continue files.append(p) files.sort(key=lambda x: str(x)) return files ``` ```python def compute_qianxin_bundle_md5(root_dir: Path) -> str: """Compute a stable MD5 for the whole skills bundle. We intentionally hash normalized path metadata + file bytes rather than relying on zip container metadata, so repeated runs are deterministic. """ h = hashlib.md5() for fpath in _iter_qianxin_hash_files(root_dir): rel = str(fpath.relative_to(root_dir)).replace(os.sep, "/") h.update(rel.encode("utf-8")) h.update(b"\0") with open(fpath, "rb") as fh: while True: chunk = fh.read(1024 * 1024) if not chunk: break h.update(chunk) h.update(b"\0") return h.hexdigest() ``` ```python # rsync: mirror skills_dir to snapshots/skills, excluding .git and __pycache__ if dest.exists(): shutil.rmtree(dest) shutil.copytree( skills_dir, dest, ignore=shutil.ignore_patterns(".git", "__pycache__", "*.pyc"), ) ...[truncated 3088 chars]- Remediation
View remediation
