skillsio 1.0.1 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +136 -13
  2. package/dist/cli.mjs +1462 -324
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -14,8 +14,8 @@ security gate so you can still move fast without running untrusted code.
14
14
 
15
15
  ## What It Does
16
16
 
17
- Every `skillsio add` command runs a local security scan **before** anything is installed. The scanner applies ~52 regex
18
- rules derived from the Snyk and ClawHavoc research, organized into 8 threat categories:
17
+ Every `skillsio add` command runs a local security scan **before** anything is installed. The scanner applies ~81 regex
18
+ rules and a correlation engine derived from the Snyk and ClawHavoc research, organized into 8 threat categories:
19
19
 
20
20
  | Category | What it catches |
21
21
  | --- | --- |
@@ -81,17 +81,111 @@ VT_API_KEY=YOUR_API_KEY npx skillsio add owner/repo
81
81
 
82
82
  `--vt-key` flag takes precedence over `VT_API_KEY` env var.
83
83
 
84
+ ### External Rules
85
+
86
+ You can extend the built-in scanner with your own rules using the `--rules` flag. This is useful for enforcing
87
+ organization-specific policies — for example, blocking references to internal infrastructure or flagging deprecated
88
+ tools.
89
+
90
+ Rules are defined in JSON files with a simple format:
91
+
92
+ ```json
93
+ {
94
+ "rules": [
95
+ {
96
+ "id": "no-internal-api",
97
+ "severity": "critical",
98
+ "description": "References internal API — may leak infrastructure details",
99
+ "pattern": "https?://internal\\.company\\.com",
100
+ "flags": "i"
101
+ },
102
+ {
103
+ "id": "no-sudo",
104
+ "severity": "high",
105
+ "description": "Skill should not require sudo access",
106
+ "pattern": "\\bsudo\\s+"
107
+ }
108
+ ]
109
+ }
110
+ ```
111
+
112
+ Each rule requires `id`, `severity` (`critical`/`high`/`medium`/`low`/`info`), `description`, and `pattern` (a regex
113
+ string). The optional `flags` field defaults to `"i"` (case-insensitive).
114
+
115
+ ```bash
116
+ # Load rules from a single file
117
+ npx skillsio add owner/repo --rules ./my-rules.json
118
+
119
+ # Load all .json rule files from a directory
120
+ npx skillsio add owner/repo --rules ./rules/
121
+ ```
122
+
123
+ External rules are applied **in addition to** the built-in ~81 rules — they never replace them. Findings from external
124
+ rules follow the same severity-based prompt flow as built-in findings.
125
+
126
+ See [docs/EXTERNAL-RULES.md](docs/EXTERNAL-RULES.md) for the full format reference, more examples, and tips for writing
127
+ rules.
128
+
129
+ ### Deep Taint Analysis (`--deep-scan`)
130
+
131
+ Regex rules detect individual dangerous patterns, but sophisticated attacks hide data flows across variables and
132
+ functions. The `--deep-scan` flag enables a lightweight taint analysis engine that tracks how data moves from
133
+ **sources** (environment variables, credential files) through variable assignments to **sinks** (network calls, exec,
134
+ file writes).
135
+
136
+ ```bash
137
+ npx skillsio add owner/repo --deep-scan
138
+ ```
139
+
140
+ What it catches that regex cannot:
141
+
142
+ ```python
143
+ # Variable-mediated exfiltration — regex sees the pieces but can't link them
144
+ key = os.environ["SECRET"] # source: env-access
145
+ encoded = b64encode(key) # taint propagates through assignment
146
+ payload = json.dumps(encoded) # ...and another hop
147
+ requests.post(url, data=payload) # sink: network → deep-env-access-to-network (critical)
148
+ ```
149
+
150
+ ```python
151
+ # getattr trick — regex misses the source entirely
152
+ env = getattr(os, 'environ') # source: getattr-trick (evades os.environ regex)
153
+ data = str(env)
154
+ requests.post(url, data=data) # → deep-getattr-trick-to-network (high)
155
+ ```
156
+
157
+ ```python
158
+ # Cross-file attack — collector.py harvests, exfil.py sends
159
+ # collector.py # exfil.py
160
+ import os # from .collector import data
161
+ secrets = os.environ.copy() # requests.post(url, data=payload)
162
+ # → deep-cross-env-access-to-network (critical)
163
+ ```
164
+
165
+ The analysis covers Python (`.py`) and JavaScript/TypeScript (`.js`, `.ts`) files. It adds zero dependencies — the
166
+ tokenizer is regex-based, not AST-based, keeping the bundle small. See [docs/deep-scan.md](docs/deep-scan.md) for
167
+ architecture details.
168
+
169
+ Deep scan findings appear alongside regex findings in the same severity-based prompt. All cross-file flows are
170
+ automatically classified as critical.
171
+
84
172
  ## Quick Start
85
173
 
86
174
  ```bash
87
175
  # Install a skill (scanned automatically)
88
176
  npx skillsio add vercel-labs/agent-skills
89
177
 
178
+ # Enable deep taint analysis for Python/JS/TS files
179
+ npx skillsio add owner/repo --deep-scan
180
+
90
181
  # Skip the scan if you trust the source
91
182
  npx skillsio add vercel-labs/agent-skills --skip-scan
92
183
 
93
184
  # Scan with VirusTotal threat intelligence
94
185
  VT_API_KEY=xxx npx skillsio add owner/repo
186
+
187
+ # Scan with custom organization rules
188
+ npx skillsio add owner/repo --rules ./company-rules.json
95
189
  ```
96
190
 
97
191
  ## CLI Reference
@@ -116,6 +210,8 @@ npx skillsio add ./my-local-skills # Local path
116
210
  | `-y, --yes` | Skip confirmation prompts |
117
211
  | `--all` | Install all skills to all agents without prompts |
118
212
  | `--skip-scan` | Skip the security scan before installation |
213
+ | `--rules <path>` | Load additional scan rules from a JSON file or directory (see [External Rules](#external-rules)) |
214
+ | `--deep-scan` | Enable deep taint analysis on Python/JS/TS files |
119
215
  | `--vt-key <key>` | VirusTotal API key for additional threat intelligence |
120
216
  | `--full-depth` | Search all subdirectories even when a root SKILL.md exists |
121
217
 
@@ -146,21 +242,21 @@ Supports **OpenCode**, **Claude Code**, **Codex**, **Cursor**, and [35 more](#su
146
242
  <!-- supported-agents:start -->
147
243
  | Agent | `--agent` | Project Path | Global Path |
148
244
  |-------|-----------|--------------|-------------|
149
- | Amp, Kimi Code CLI | `amp`, `kimi-cli` | `.agents/skills/` | `~/.config/agents/skills/` |
245
+ | Amp, Kimi Code CLI, Replit | `amp`, `kimi-cli`, `replit` | `.agents/skills/` | `~/.config/agents/skills/` |
150
246
  | Antigravity | `antigravity` | `.agent/skills/` | `~/.gemini/antigravity/skills/` |
151
- | Augment | `augment` | `.augment/rules/` | `~/.augment/rules/` |
247
+ | Augment | `augment` | `.augment/skills/` | `~/.augment/skills/` |
152
248
  | Claude Code | `claude-code` | `.claude/skills/` | `~/.claude/skills/` |
153
249
  | OpenClaw | `openclaw` | `skills/` | `~/.moltbot/skills/` |
154
250
  | Cline | `cline` | `.cline/skills/` | `~/.cline/skills/` |
155
251
  | CodeBuddy | `codebuddy` | `.codebuddy/skills/` | `~/.codebuddy/skills/` |
156
- | Codex | `codex` | `.codex/skills/` | `~/.codex/skills/` |
252
+ | Codex | `codex` | `.agents/skills/` | `~/.codex/skills/` |
157
253
  | Command Code | `command-code` | `.commandcode/skills/` | `~/.commandcode/skills/` |
158
254
  | Continue | `continue` | `.continue/skills/` | `~/.continue/skills/` |
159
255
  | Crush | `crush` | `.crush/skills/` | `~/.config/crush/skills/` |
160
256
  | Cursor | `cursor` | `.cursor/skills/` | `~/.cursor/skills/` |
161
257
  | Droid | `droid` | `.factory/skills/` | `~/.factory/skills/` |
162
- | Gemini CLI | `gemini-cli` | `.gemini/skills/` | `~/.gemini/skills/` |
163
- | GitHub Copilot | `github-copilot` | `.github/skills/` | `~/.copilot/skills/` |
258
+ | Gemini CLI | `gemini-cli` | `.agents/skills/` | `~/.gemini/skills/` |
259
+ | GitHub Copilot | `github-copilot` | `.agents/skills/` | `~/.copilot/skills/` |
164
260
  | Goose | `goose` | `.goose/skills/` | `~/.config/goose/skills/` |
165
261
  | Junie | `junie` | `.junie/skills/` | `~/.junie/skills/` |
166
262
  | iFlow CLI | `iflow-cli` | `.iflow/skills/` | `~/.iflow/skills/` |
@@ -170,12 +266,11 @@ Supports **OpenCode**, **Claude Code**, **Codex**, **Cursor**, and [35 more](#su
170
266
  | MCPJam | `mcpjam` | `.mcpjam/skills/` | `~/.mcpjam/skills/` |
171
267
  | Mistral Vibe | `mistral-vibe` | `.vibe/skills/` | `~/.vibe/skills/` |
172
268
  | Mux | `mux` | `.mux/skills/` | `~/.mux/skills/` |
173
- | OpenCode | `opencode` | `.opencode/skills/` | `~/.config/opencode/skills/` |
269
+ | OpenCode | `opencode` | `.agents/skills/` | `~/.config/opencode/skills/` |
174
270
  | OpenHands | `openhands` | `.openhands/skills/` | `~/.openhands/skills/` |
175
271
  | Pi | `pi` | `.pi/skills/` | `~/.pi/agent/skills/` |
176
272
  | Qoder | `qoder` | `.qoder/skills/` | `~/.qoder/skills/` |
177
273
  | Qwen Code | `qwen-code` | `.qwen/skills/` | `~/.qwen/skills/` |
178
- | Replit | `replit` | `.agents/skills/` | N/A (project-only) |
179
274
  | Roo Code | `roo` | `.roo/skills/` | `~/.roo/skills/` |
180
275
  | Trae | `trae` | `.trae/skills/` | `~/.trae/skills/` |
181
276
  | Trae CN | `trae-cn` | `.trae/skills/` | `~/.trae-cn/skills/` |
@@ -194,8 +289,6 @@ The CLI automatically detects which coding agents you have installed.
194
289
  | --- | --- |
195
290
  | `VT_API_KEY` | VirusTotal API key for optional threat intelligence during security scans |
196
291
  | `INSTALL_INTERNAL_SKILLS` | Set to `1` to show and install skills marked as `internal: true` |
197
- | `DISABLE_TELEMETRY` | Disable anonymous usage telemetry |
198
- | `DO_NOT_TRACK` | Alternative way to disable telemetry |
199
292
 
200
293
  ## Development
201
294
 
@@ -210,17 +303,39 @@ pnpm format # Format code with Prettier
210
303
 
211
304
  ### Scanner Architecture
212
305
 
213
- - `src/scanner.ts` — Rules engine. Defines ~52 regex rules across 8 threat categories, runs them against all skill
214
- files (.md, .txt, .yaml, .json, .sh, .py, .js, .ts, .ps1, .bat, .cmd).
306
+ - `src/scanner.ts` — Rules engine. Defines ~81 regex rules across 8 threat categories, a correlation engine for
307
+ multi-signal detection, and optional deep taint analysis integration. Supports loading external rules from JSON
308
+ files via `--rules`.
215
309
  - `src/scanner-ui.ts` — Presentation layer. Displays findings by severity, runs optional VT lookups, handles
216
310
  escalation logic and user confirmation prompts.
217
311
  - `src/vt.ts` — VirusTotal API client. SHA-256 hashing, `GET /api/v3/files/{hash}` lookup, verdict mapping, graceful
218
312
  error handling.
313
+ - `src/deep-scan/` — Deep taint analysis engine (enabled via `--deep-scan`). Regex-based tokenizers extract sources,
314
+ sinks, and assignments from Python/JS/TS files; a forward taint tracker propagates data flow; a cross-file analyzer
315
+ detects multi-file attack patterns via import graph analysis. See [docs/deep-scan.md](docs/deep-scan.md).
219
316
  - `src/add.ts` — Integration point. The scanner is wired into all 4 install paths (GitHub/git repos, remote providers,
220
317
  well-known endpoints, legacy Mintlify).
221
318
 
222
319
  ## Changelog
223
320
 
321
+ ### 1.1.1
322
+
323
+ - Removed anonymous usage telemetry inherited from the original Vercel `skills` CLI
324
+ - The upstream tool sent events to `https://add-skill.vercel.sh/t` on every command (install, remove, find, check, update) — this has been completely stripped out
325
+ - Removed `DISABLE_TELEMETRY` and `DO_NOT_TRACK` environment variables (no longer needed)
326
+ - Added 12 more regex rules to the scanner
327
+
328
+ ### 1.1.0
329
+
330
+ - Added `--rules <path>` flag to load external scan rules from JSON files or directories
331
+ - External rules are applied alongside built-in rules, supporting organization-specific policies
332
+ - See [docs/EXTERNAL-RULES.md](docs/EXTERNAL-RULES.md) for format documentation and examples
333
+ - **Deep taint analysis** (`--deep-scan`): lightweight forward taint propagation for Python and JS/TS files
334
+ - Tracks data flow from sources (env vars, credential files, getattr tricks) through variable chains to sinks (network
335
+ calls, exec, file writes)
336
+ - Cross-file analysis detects multi-file exfiltration patterns via import graph resolution
337
+ - Zero new dependencies — regex-based tokenizers keep the bundle small
338
+
224
339
  ### 1.0.1
225
340
 
226
341
  - Critical security prompts now default to **No** — users must explicitly confirm to install skills flagged as malicious
@@ -232,6 +347,14 @@ pnpm format # Format code with Prettier
232
347
  - URL transparency: all external URLs in skill files are shown before installation
233
348
  - Scanner rules informed by Snyk and ClawHavoc research
234
349
 
350
+ ## Research
351
+
352
+ The scanner rules are informed by the following research into malicious agent skills:
353
+
354
+ - **Snyk (2025)** — [Analysis of 3,984 published agent skills](https://snyk.io/blog/), finding 76 confirmed malicious skills (13.4% of clawhub.ai had critical issues). Identified core attack taxonomy: data exfiltration, prompt injection, credential theft, and obfuscated payloads.
355
+ - **Koi Security (2025)** — [ClawHavoc: 341 Malicious ClawedBot Skills](https://www.koi.ai/blog/clawhavoc-341-malicious-clawedbot-skills-found-by-the-bot-they-were-targeting). Documented AMOS stealer droppers, password-protected archives, base64 payloads, macOS quarantine bypasses, and reverse shells in the wild.
356
+ - **arxiv 2602.06547v1 (2025)** — [Malicious Agent Skills at Scale](https://arxiv.org/abs/2602.06547v1). Large-scale analysis identifying attack taxonomies (E1-E3 exfiltration, P1-P4 prompt injection, SC1-SC3 supply chain, PE2-PE3 privilege escalation), MCP server abuse, agent hook interception, permission bypass flags, environment-gated sleeper patterns, invisible Unicode instruction smuggling, and the "industrial actor fingerprint" (credential access + remote execution, 97.6% sensitivity).
357
+
235
358
  ## Acknowledgments
236
359
 
237
360
  This project is a fork of [skills](https://github.com/vercel-labs/skills) by