#!/usr/bin/env python3 """ Security Scanner — Agentic Awesome Skills Scans skill content for dangerous command patterns. Can be used as a module or run standalone: node tools/scripts/run-python.js tools/scripts/security_scanner.py node tools/scripts/run-python.js tools/scripts/security_scanner.py --strict """ from __future__ import annotations import argparse import re import sys from dataclasses import dataclass, field from pathlib import Path from _project_paths import find_repo_root from validate_skills import configure_utf8_output, parse_frontmatter # --------------------------------------------------------------------------- # Security pattern definitions # --------------------------------------------------------------------------- @dataclass(frozen=True) class SecurityPattern: code: str regex: str severity: str # error | warning | info description: str rationale: str SECURITY_PATTERNS: list[SecurityPattern] = [ SecurityPattern( code="SEC001", regex=r"rm\s+-[rf]{1,2}\s+/(?!\S)", severity="error", description="Destructive rm targeting root filesystem", rationale="rm -rf / deletes the entire filesystem; always destructive when unguarded.", ), SecurityPattern( code="SEC002", regex=r"curl\b[^\n]*\|\s*(?:bash|sh|zsh)|(?:bash|sh|zsh)\s+<\s*\(\s*curl\b", severity="error", description="Remote code execution: curl piped to shell", rationale="Pipes untrusted remote content directly into a shell without integrity verification.", ), SecurityPattern( code="SEC003", regex=r"wget\b[^\n]*\|\s*(?:sh|bash|zsh)|(?:bash|sh|zsh)\s+<\s*\(\s*wget\b", severity="error", description="Remote code execution: wget | sh", rationale="Same class of risk as curl | bash — downloads and executes without verification.", ), SecurityPattern( code="SEC004", regex=r"\bInvoke-Expression\b", severity="error", description="PowerShell RCE: Invoke-Expression", rationale="Evaluates arbitrary strings as PowerShell code; classic RCE vector.", ), SecurityPattern( code="SEC005", regex=r"\biex\b", severity="warning", description="PowerShell alias: iex (Invoke-Expression)", rationale="Alias for Invoke-Expression; context-dependent but frequently abused.", ), SecurityPattern( code="SEC006", regex=r"chmod\s+[0-7]*[2367](?:\s|$)", severity="warning", description="World-writable permission (other-write bit set)", rationale="Modes where the last octal digit is 2/3/6/7 grant write access to all users.", ), SecurityPattern( code="SEC007", regex=r"(?) and colon forms # () documented in skill-template.md. _ALLOWLIST_MARKERS = ( "# security-allowlist", "// security-allowlist", "