Every skill is scanned before installation and upgrade. The current built-in scanner runs three rule categories against skill content and ancillary files.
| Rule ID | What It Detects | Default Severity |
|---|---|---|
SCAN_DANGEROUS_PATTERN |
rm -rf /, curl|bash, reverse shells, credential reads, crypto mining, eval, SSH key exfiltration |
Critical / High / Medium |
SCAN_PROMPT_INJECTION |
Instruction overrides ("ignore previous instructions"), Unicode tricks (zero-width chars, RTL override), concealment instructions, large encoded blocks | High / Medium |
SCAN_SIZE_ANOMALY |
SKILL.md > 100KB, single file > 500KB, total files > 5MB, > 50 ancillary files | Medium / Low |
| Severity | Value | Description |
|---|---|---|
| Critical | 4 | Always blocks, even with --force |
| High | 3 | Blocks by default |
| Medium | 2 | Blocks unless --force is passed |
| Low | 1 | Logged, never blocks |
| Info | 0 | Informational only |
| Finding Severity | Default Behavior | With --force |
|---|---|---|
| Critical | Blocked | Blocked (cannot bypass) |
| High | Blocked | Allowed |
| Medium | Blocked | Allowed |
| Low | Logged | Logged |
| Info | Logged | Logged |
The block threshold is configurable via block_severity in config. The default is "high", meaning high and critical findings block. Setting it to "medium" would also block medium findings without --force.
In ~/.skillpm/config.toml:
[security.scan]
enabled = true # set to false to disable scanning entirely
block_severity = "high" # minimum severity that blocks: critical, high, medium, low, info
disabled_rules = [] # rule IDs to skip, e.g. ["SCAN_PROMPT_INJECTION"]$ skillpm install my-repo/suspicious-skill
SEC_SCAN_BLOCKED: [HIGH] SCAN_DANGEROUS_PATTERN (SKILL.md: Code execution via subprocess.run); use --force to proceed$ skillpm install my-repo/admin-tool --force
installed admin-tool@v1.2.0[security.scan]
disabled_rules = ["SCAN_PROMPT_INJECTION"][security.scan]
enabled = falseScanning runs automatically during:
skillpm install— scans each skill before committing to diskskillpm upgrade— scans upgraded content before replacingskillpm sync— scans skills during the upgrade phase
The scanner is not invoked during inject, doctor, or list operations.
The SCAN_DANGEROUS_PATTERN rule checks for:
Critical patterns:
- Destructive file deletion (
rm -rf /,rm -rf ~/,rm -rf $HOME) - Remote code execution pipes (
curl ... | sh,wget ... | sh) - Obfuscated execution (
base64 -d | sh) - Sensitive file access (
/etc/shadow,/etc/passwd) - Reverse shells (
mkfifo ... nc,nc -e /bin/) - SSH key exfiltration (
~/.ssh/id_rsa) - Crypto mining indicators (
stratum+tcp://,xmrig,minerd) - Dangerous permissions (
chmod 777 /) - Arbitrary code execution (
eval()
High patterns:
- Code execution in non-shell contexts (
os.exec,subprocess.run,child_process.exec) - Environment variable harvesting (
os.environ) - Data exfiltration (
curl -d,wget --post-data) - Credential file references (
.env,credentials.json,secrets.yaml) - Global git config modification
- Package installation commands (
pip install,npm install)
Medium patterns:
sudousage