guard-scanner 1.0.0

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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Guava & Dee
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,586 @@
1
+ <p align="center">
2
+ <h1 align="center">🛡️ guard-scanner</h1>
3
+ <p align="center">
4
+ <strong>Static security scanner for AI agent skills</strong><br>
5
+ Detect prompt injection, credential theft, exfiltration, identity hijacking, and 14 more threat categories.
6
+ </p>
7
+ <p align="center">
8
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License"></a>
9
+ <img src="https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen" alt="Node.js 18+">
10
+ <img src="https://img.shields.io/badge/dependencies-0-success" alt="Zero Dependencies">
11
+ <img src="https://img.shields.io/badge/tests-45%2F45-brightgreen" alt="Tests Passing">
12
+ <img src="https://img.shields.io/badge/patterns-170%2B-orange" alt="170+ Patterns">
13
+ </p>
14
+ </p>
15
+
16
+ ---
17
+
18
+ ## Why This Exists
19
+
20
+ In February 2026, [Snyk's ToxicSkills audit](https://snyk.io) of 3,984 AI agent skills revealed:
21
+ - **36.8%** contained at least one security flaw
22
+ - **13.4%** had critical-level issues
23
+ - **76 active malicious payloads** for credential theft, backdoors, and data exfiltration
24
+
25
+ The AI agent skill ecosystem has the same supply-chain security problem that npm and PyPI had in their early days — except agent skills inherit **full shell access, file system permissions, and environment variables** of the host agent.
26
+
27
+ **guard-scanner** was born from a real 3-day identity hijack incident where an AI agent's personality files were silently overwritten by a malicious skill. There was no scanner that could detect it. Now there is. 🍈
28
+
29
+ ---
30
+
31
+ ## Features
32
+
33
+ | Feature | Description |
34
+ |---|---|
35
+ | **17 Threat Categories** | Snyk ToxicSkills taxonomy + OWASP MCP Top 10 + Identity Hijacking |
36
+ | **170+ Detection Patterns** | Regex-based static analysis covering code, docs, and data files |
37
+ | **IoC Database** | Known malicious IPs, domains, URLs, usernames, and typosquat names |
38
+ | **Data Flow Analysis** | Lightweight JS analysis: secret reads → network calls → exec chains |
39
+ | **Cross-File Analysis** | Phantom references, base64 fragment assembly, multi-file exfil detection |
40
+ | **Shannon Entropy** | High-entropy string detection for leaked secrets and API keys |
41
+ | **Dependency Chain Scan** | Risky packages, lifecycle scripts, wildcard versions, git dependencies |
42
+ | **4 Output Formats** | Terminal (with colors), JSON, [SARIF 2.1.0](https://sarifweb.azurewebsites.net), HTML dashboard |
43
+ | **Plugin API** | Extend with custom detection rules via JS modules |
44
+ | **Ignore Files** | Whitelist trusted skills and patterns via `.guard-scanner-ignore` |
45
+ | **Zero Dependencies** | Pure Node.js stdlib. Nothing to install, nothing to audit. |
46
+ | **CI/CD Ready** | `--fail-on-findings` exit code + SARIF for GitHub Code Scanning |
47
+
48
+ ---
49
+
50
+ ## Quick Start
51
+
52
+ ```bash
53
+ # Scan a skill directory (each subdirectory = one skill)
54
+ npx guard-scanner ./skills/
55
+
56
+ # Verbose output with category breakdown
57
+ npx guard-scanner ./skills/ --verbose
58
+
59
+ # Strict mode (lower thresholds)
60
+ npx guard-scanner ./skills/ --strict
61
+
62
+ # Full audit: verbose + deps + all output formats
63
+ npx guard-scanner ./skills/ --verbose --check-deps --json --sarif --html
64
+ ```
65
+
66
+ ### Installation (Optional)
67
+
68
+ ```bash
69
+ # Global install
70
+ npm install -g guard-scanner
71
+
72
+ # Or use directly via npx (no install needed)
73
+ npx guard-scanner ./skills/
74
+ ```
75
+
76
+ ### As an OpenClaw Skill
77
+
78
+ ```bash
79
+ openclaw skill install guard-scanner
80
+ guard-scanner ~/.openclaw/workspace/skills/ --self-exclude --verbose
81
+ ```
82
+
83
+ ---
84
+
85
+ ## Threat Categories
86
+
87
+ guard-scanner covers **17 threat categories** derived from three taxonomies:
88
+
89
+ | # | Category | Based On | Severity | What It Detects |
90
+ |---|----------|----------|----------|----------------|
91
+ | 1 | **Prompt Injection** | Snyk ToxicSkills | CRITICAL | Invisible Unicode (ZWSP, BiDi), homoglyphs (Cyrillic/Greek/Math), role override, system tag injection, base64 execution instructions |
92
+ | 2 | **Malicious Code** | Snyk ToxicSkills | CRITICAL | `eval()`, `Function()` constructor, `child_process`, reverse shells, raw sockets, sandbox detection |
93
+ | 3 | **Suspicious Downloads** | Snyk ToxicSkills | CRITICAL | `curl\|bash` pipes, executable downloads, password-protected archives, prerequisite fraud |
94
+ | 4 | **Credential Handling** | Snyk ToxicSkills | HIGH | `.env` file reads, SSH key access, wallet seed phrases, credential echo/print, `sudo` in docs |
95
+ | 5 | **Secret Detection** | Snyk ToxicSkills | CRITICAL | AWS Access Keys (`AKIA...`), GitHub tokens (`ghp_/ghs_`), embedded private keys, high-entropy strings |
96
+ | 6 | **Exfiltration** | Snyk ToxicSkills | CRITICAL | webhook.site/requestbin.com/hookbin, POST with secrets, `curl --data`, DNS tunneling |
97
+ | 7 | **Unverifiable Deps** | Snyk ToxicSkills | HIGH | Remote dynamic imports, non-CDN script loading |
98
+ | 8 | **Financial Access** | Snyk ToxicSkills | HIGH | Crypto private keys, `sendTransaction`, Stripe/PayPal/Plaid API calls |
99
+ | 9 | **Obfuscation** | Snyk ToxicSkills | HIGH | Hex strings, `atob→eval` chains, `String.fromCharCode`, array join, `base64 -d\|bash` |
100
+ | 10 | **Prerequisites Fraud** | Snyk ToxicSkills | CRITICAL | Download-in-prerequisites, terminal paste instructions |
101
+ | 11 | **Leaky Skills** | Snyk ToxicSkills | CRITICAL | "Save API key in memory", "Share token with user", verbatim secrets in curl, PII collection, session log export |
102
+ | 12 | **Memory Poisoning** | Palo Alto IBC | CRITICAL | SOUL.md/IDENTITY.md modification, agent memory writes, behavioral rule override, persistence instructions |
103
+ | 13 | **Prompt Worm** | Palo Alto IBC | CRITICAL | Self-replication instructions, agent-to-agent propagation, hidden instruction embedding, CSS-hidden content |
104
+ | 14 | **Persistence** | MITRE ATT&CK | HIGH | Scheduled tasks/cron, startup execution, LaunchAgents/systemd |
105
+ | 15 | **CVE Patterns** | CVE Database | CRITICAL | CVE-2026-25253 `gatewayUrl` injection, sandbox disabling, xattr Gatekeeper bypass, WebSocket origin bypass |
106
+ | 16 | **MCP Security** | OWASP MCP Top 10 | CRITICAL | Tool poisoning (`<IMPORTANT>`), schema poisoning (malicious defaults), token leaks, shadow server registration, SSRF metadata endpoints |
107
+ | 17 | **Identity Hijacking** | Original Research | CRITICAL | SOUL.md/IDENTITY.md overwrite/redirect/sed/echo/Python/Node.js writes, persona swap instructions, memory wipe, name override |
108
+
109
+ > **Category 17 (Identity Hijacking)** is unique to guard-scanner. It was developed from direct experience with a real attack where an agent's identity files were silently replaced. Detection patterns are open-source; verification logic remains private.
110
+
111
+ ---
112
+
113
+ ## Output Formats
114
+
115
+ ### Terminal (Default)
116
+
117
+ ```
118
+ 🛡️ guard-scanner v1.0.0
119
+ ══════════════════════════════════════════════════════
120
+ 📂 Scanning: ./skills/
121
+ 📦 Skills found: 22
122
+
123
+ 🟢 my-safe-skill — CLEAN (risk: 0)
124
+ 🟢 another-skill — LOW RISK (risk: 5)
125
+ 🟡 suspicious-one — SUSPICIOUS (risk: 45)
126
+ 📁 credential-handling
127
+ 🔴 [HIGH] Reading .env file — scripts/main.js:12
128
+ 🔴 [HIGH] SSH key access — scripts/deploy.sh:8
129
+ 🔴 evil-skill — MALICIOUS (risk: 100)
130
+ 📁 malicious-code
131
+ 💀 [CRITICAL] Reverse shell — scripts/backdoor.js:3
132
+ 📁 exfiltration
133
+ 💀 [CRITICAL] Known exfiltration endpoint — scripts/exfil.js:15
134
+
135
+ ══════════════════════════════════════════════════════
136
+ 📊 Scan Summary
137
+ Scanned: 22
138
+ 🟢 Clean: 18
139
+ 🟢 Low Risk: 2
140
+ 🟡 Suspicious: 1
141
+ 🔴 Malicious: 1
142
+ Safety Rate: 91%
143
+ ══════════════════════════════════════════════════════
144
+ ```
145
+
146
+ ### JSON (`--json`)
147
+
148
+ Writes `guard-scanner-report.json` with full findings, stats, recommendations, and IoC version.
149
+
150
+ ### SARIF (`--sarif`)
151
+
152
+ Writes `guard-scanner.sarif` — [SARIF 2.1.0](https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/sarif-support-for-code-scanning) compatible. Upload to GitHub Code Scanning:
153
+
154
+ ```yaml
155
+ # .github/workflows/scan.yml
156
+ - name: Scan agent skills
157
+ run: npx guard-scanner ./skills/ --sarif --fail-on-findings
158
+
159
+ - name: Upload SARIF
160
+ uses: github/codeql-action/upload-sarif@v3
161
+ with:
162
+ sarif_file: skills/guard-scanner.sarif
163
+ ```
164
+
165
+ ### HTML (`--html`)
166
+
167
+ Generates a dark-mode dashboard with stats grid and per-skill finding tables. Open in any browser.
168
+
169
+ ---
170
+
171
+ ## Risk Scoring
172
+
173
+ Each skill receives a **risk score (0–100)** based on:
174
+
175
+ ### Base Score
176
+ | Severity | Weight |
177
+ |----------|--------|
178
+ | CRITICAL | 40 points |
179
+ | HIGH | 15 points |
180
+ | MEDIUM | 5 points |
181
+ | LOW | 2 points |
182
+
183
+ ### Amplification Rules
184
+
185
+ Certain combinations multiply the base score:
186
+
187
+ | Combination | Multiplier | Rationale |
188
+ |---|---|---|
189
+ | Credential handling + Exfiltration | **×2** | Classic steal-and-send pattern |
190
+ | Credential handling + Command exec | **×1.5** | Credential-powered RCE |
191
+ | Obfuscation + Malicious code | **×2** | Hiding malicious intent |
192
+ | Lifecycle script exec | **×2** | npm supply chain attack |
193
+ | BiDi characters + other findings | **×1.5** | Text direction attack as vector |
194
+ | Leaky skills + Exfiltration | **×2** | Secret leak through LLM context |
195
+ | Memory poisoning | **×1.5** | Persistent compromise |
196
+ | Prompt worm | **×2** | Self-replicating threat |
197
+ | Persistence + (malicious\|credential\|memory) | **×1.5** | Survives session restart |
198
+ | Identity hijacking | **×2** | Core identity compromise |
199
+ | Identity hijacking + Persistence | **min 90** | Full agent takeover |
200
+ | Known IoC (IP/URL/typosquat) | **= 100** | Confirmed malicious |
201
+
202
+ ### Verdict Thresholds
203
+
204
+ | Mode | Suspicious | Malicious |
205
+ |------|-----------|-----------|
206
+ | Normal | ≥ 30 | ≥ 80 |
207
+ | Strict (`--strict`) | ≥ 20 | ≥ 60 |
208
+
209
+ ---
210
+
211
+ ## Data Flow Analysis
212
+
213
+ guard-scanner performs lightweight static analysis on JavaScript/TypeScript files to detect **multi-step attack patterns** that individual regex rules miss:
214
+
215
+ ```
216
+ Secret Read (L36) ─── process.env.API_KEY ───→ Network Call (L56) ─── fetch() ───→ 🚨 CRITICAL
217
+ AST_CRED_TO_NET
218
+ ```
219
+
220
+ ### Detected Chains
221
+
222
+ | Pattern ID | Chain | Severity |
223
+ |---|---|---|
224
+ | `AST_CRED_TO_NET` | Secret read → Network call | CRITICAL |
225
+ | `AST_CRED_TO_EXEC` | Secret read → Command exec | HIGH |
226
+ | `AST_SUSPICIOUS_IMPORTS` | `child_process` + network module | HIGH |
227
+ | `AST_EXFIL_TRIFECTA` | `fs` + `child_process` + `http/https` | CRITICAL |
228
+ | `AST_SECRET_IN_URL` | Secret interpolated into URL | CRITICAL |
229
+
230
+ ---
231
+
232
+ ## IoC Database
233
+
234
+ Built-in Indicators of Compromise from real-world incidents:
235
+
236
+ | Type | Examples | Source |
237
+ |------|----------|--------|
238
+ | **IPs** | `91.92.242.30` (C2) | ClawHavoc campaign |
239
+ | **Domains** | `webhook.site`, `requestbin.com`, `hookbin.com`, `pipedream.net` | Common exfil endpoints |
240
+ | **URLs** | `glot.io/snippets/hfd3x9ueu5` | ClawHavoc macOS payload |
241
+ | **Usernames** | `zaycv`, `Ddoy233`, `Sakaen736jih` | Known malicious actors |
242
+ | **Filenames** | `openclaw-agent.zip`, `openclawcli.zip` | Trojanized installers |
243
+ | **Typosquats** | `clawhub`, `polymarket-trader`, `auto-updater-agent` + 20 more | ClawHavoc, Polymarket, Snyk ToxicSkills |
244
+
245
+ Any match against the IoC database automatically sets risk to **100 (MALICIOUS)**.
246
+
247
+ ---
248
+
249
+ ## Plugin API
250
+
251
+ Extend guard-scanner with custom detection rules:
252
+
253
+ ```javascript
254
+ // my-org-rules.js
255
+ module.exports = {
256
+ name: 'my-org-security-rules',
257
+ patterns: [
258
+ {
259
+ id: 'ORG_INTERNAL_API',
260
+ cat: 'data-leak',
261
+ regex: /api\.internal\.mycompany\.com/gi,
262
+ severity: 'CRITICAL',
263
+ desc: 'Internal API endpoint exposed in skill',
264
+ all: true // scan all file types
265
+ },
266
+ {
267
+ id: 'ORG_STAGING_CRED',
268
+ cat: 'secret-detection',
269
+ regex: /staging[_-](?:key|token|password)\s*[:=]\s*['"][^'"]+['"]/gi,
270
+ severity: 'HIGH',
271
+ desc: 'Staging credential hardcoded',
272
+ codeOnly: true // only scan code files
273
+ }
274
+ ]
275
+ };
276
+ ```
277
+
278
+ ```bash
279
+ guard-scanner ./skills/ --plugin ./my-org-rules.js
280
+ ```
281
+
282
+ ### Pattern Schema
283
+
284
+ | Field | Type | Required | Description |
285
+ |---|---|---|---|
286
+ | `id` | string | ✅ | Unique pattern identifier (e.g., `ORG_001`) |
287
+ | `cat` | string | ✅ | Category name for grouping |
288
+ | `regex` | RegExp | ✅ | Detection pattern (use `g` flag) |
289
+ | `severity` | string | ✅ | `CRITICAL` \| `HIGH` \| `MEDIUM` \| `LOW` |
290
+ | `desc` | string | ✅ | Human-readable description |
291
+ | `all` | boolean | | Scan all file types |
292
+ | `codeOnly` | boolean | | Only scan code files (.js, .ts, .py, .sh, etc.) |
293
+ | `docOnly` | boolean | | Only scan documentation files (.md, .txt, etc.) |
294
+
295
+ ### Custom Rules via JSON
296
+
297
+ Alternatively, use a JSON rules file:
298
+
299
+ ```json
300
+ [
301
+ {
302
+ "id": "CUSTOM_001",
303
+ "pattern": "dangerous_function\\(",
304
+ "flags": "gi",
305
+ "severity": "HIGH",
306
+ "cat": "malicious-code",
307
+ "desc": "Dangerous function call"
308
+ }
309
+ ]
310
+ ```
311
+
312
+ ```bash
313
+ guard-scanner ./skills/ --rules ./custom-rules.json
314
+ ```
315
+
316
+ ---
317
+
318
+ ## Ignore Files
319
+
320
+ Create `.guard-scanner-ignore` (or `.guava-guard-ignore`) in the scan directory:
321
+
322
+ ```gitignore
323
+ # Ignore trusted skills
324
+ my-trusted-skill
325
+ internal-tool
326
+
327
+ # Ignore specific patterns (false positives)
328
+ pattern:MAL_CHILD
329
+ pattern:CRED_ENV_REF
330
+ ```
331
+
332
+ ---
333
+
334
+ ## CLI Reference
335
+
336
+ ```
337
+ Usage: guard-scanner [scan-dir] [options]
338
+
339
+ Arguments:
340
+ scan-dir Directory to scan (default: current directory)
341
+
342
+ Options:
343
+ --verbose, -v Show detailed findings with categories and samples
344
+ --json Write JSON report to scan-dir/guard-scanner-report.json
345
+ --sarif Write SARIF 2.1.0 report for CI/CD integration
346
+ --html Write HTML dashboard report
347
+ --self-exclude Skip scanning the guard-scanner skill itself
348
+ --strict Lower detection thresholds (suspicious: 20, malicious: 60)
349
+ --summary-only Only print the summary table
350
+ --check-deps Scan package.json for dependency chain risks
351
+ --rules <file> Load custom rules from JSON file
352
+ --plugin <file> Load plugin module (repeatable)
353
+ --fail-on-findings Exit code 1 if any findings (for CI/CD)
354
+ --help, -h Show help
355
+ ```
356
+
357
+ ### Exit Codes
358
+
359
+ | Code | Meaning |
360
+ |------|---------|
361
+ | 0 | No malicious skills detected |
362
+ | 1 | Malicious skill(s) detected, or `--fail-on-findings` with any findings |
363
+ | 2 | Invalid scan directory |
364
+
365
+ ---
366
+
367
+ ## Architecture
368
+
369
+ ```
370
+ guard-scanner/
371
+ ├── src/
372
+ │ ├── scanner.js # GuardScanner class — core scan engine
373
+ │ ├── patterns.js # 170+ threat detection patterns (Cat 1–17)
374
+ │ ├── ioc-db.js # Indicators of Compromise database
375
+ │ └── cli.js # CLI entry point and argument parser
376
+ ├── test/
377
+ │ ├── scanner.test.js # 45 tests across 10 sections
378
+ │ └── fixtures/ # Malicious + clean skill samples
379
+ ├── package.json # Zero dependencies, node --test
380
+ ├── CHANGELOG.md
381
+ ├── LICENSE # MIT
382
+ └── README.md
383
+ ```
384
+
385
+ ### How Scanning Works
386
+
387
+ ```
388
+ ┌──────────────────┐
389
+ │ CLI / API │
390
+ └────────┬─────────┘
391
+
392
+ ┌────────▼─────────┐
393
+ │ GuardScanner │
394
+ │ constructor() │
395
+ │ • Load plugins │
396
+ │ • Load rules │
397
+ │ • Set thresholds│
398
+ └────────┬─────────┘
399
+
400
+ ┌────────▼─────────┐
401
+ │ scanDirectory() │
402
+ │ • Load ignore │
403
+ │ • Enumerate │
404
+ └────────┬─────────┘
405
+
406
+ ┌──────────────┼──────────────┐
407
+ │ │ │
408
+ ┌────────▼──────┐ ┌────▼────┐ ┌───────▼──────┐
409
+ │ Per-Skill │ │ Per- │ │ Structural │
410
+ │ File Scan │ │ File │ │ Checks │
411
+ │ │ │ IoC │ │ │
412
+ │ • Pattern │ │ Check │ │ • SKILL.md │
413
+ │ matching │ │ │ │ • Hidden │
414
+ │ • Secret │ │ • IPs │ │ files │
415
+ │ entropy │ │ • URLs │ │ • Deps │
416
+ │ • Data flow │ │ • Names │ │ • Cross-file │
417
+ │ • Custom rules│ │ │ │ │
418
+ └───────┬───────┘ └────┬────┘ └──────┬───────┘
419
+ │ │ │
420
+ └──────────────┼──────────────┘
421
+
422
+ ┌────────▼─────────┐
423
+ │ calculateRisk() │
424
+ │ • Base score │
425
+ │ • Amplifiers │
426
+ │ • IoC override │
427
+ └────────┬─────────┘
428
+
429
+ ┌────────▼─────────┐
430
+ │ Output │
431
+ │ • Terminal │
432
+ │ • JSON │
433
+ │ • SARIF 2.1.0 │
434
+ │ • HTML │
435
+ └──────────────────┘
436
+ ```
437
+
438
+ ---
439
+
440
+ ## CI/CD Integration
441
+
442
+ ### GitHub Actions
443
+
444
+ ```yaml
445
+ name: Skill Security Scan
446
+ on: [push, pull_request]
447
+
448
+ jobs:
449
+ scan:
450
+ runs-on: ubuntu-latest
451
+ steps:
452
+ - uses: actions/checkout@v4
453
+
454
+ - name: Run guard-scanner
455
+ run: npx guard-scanner ./skills/ --sarif --strict --fail-on-findings
456
+
457
+ - name: Upload SARIF results
458
+ if: always()
459
+ uses: github/codeql-action/upload-sarif@v3
460
+ with:
461
+ sarif_file: skills/guard-scanner.sarif
462
+ ```
463
+
464
+ ### Pre-commit Hook
465
+
466
+ ```bash
467
+ #!/bin/bash
468
+ # .git/hooks/pre-commit
469
+ npx guard-scanner ./skills/ --strict --fail-on-findings --summary-only
470
+ ```
471
+
472
+ ---
473
+
474
+ ## Programmatic API
475
+
476
+ ```javascript
477
+ const { GuardScanner } = require('guard-scanner');
478
+
479
+ const scanner = new GuardScanner({
480
+ verbose: false,
481
+ strict: true,
482
+ checkDeps: true,
483
+ summaryOnly: true,
484
+ plugins: ['./my-plugin.js']
485
+ });
486
+
487
+ scanner.scanDirectory('./skills/');
488
+
489
+ // Access results
490
+ console.log(scanner.stats); // { scanned, clean, low, suspicious, malicious }
491
+ console.log(scanner.findings); // Array of per-skill findings
492
+ console.log(scanner.toJSON()); // Full JSON report
493
+ console.log(scanner.toSARIF('.')); // SARIF 2.1.0 object
494
+ console.log(scanner.toHTML()); // HTML string
495
+ ```
496
+
497
+ ---
498
+
499
+ ## Test Results
500
+
501
+ ```
502
+ ℹ tests 45
503
+ ℹ suites 10
504
+ ℹ pass 45
505
+ ℹ fail 0
506
+ ℹ duration_ms 83ms
507
+ ```
508
+
509
+ | Suite | Tests | Coverage |
510
+ |-------|-------|----------|
511
+ | Malicious Skill Detection | 16 | Cat 1,2,3,4,5,6,9,11,12,17 + IoC + DataFlow + DepChain |
512
+ | False Positive Test | 2 | Clean skill → zero false positives |
513
+ | Risk Score Calculation | 5 | Empty, single, combo amplifiers, IoC override |
514
+ | Verdict Determination | 5 | All verdicts + strict mode |
515
+ | Output Formats | 4 | JSON + SARIF 2.1.0 + HTML structure |
516
+ | Pattern Database | 4 | 100+ count, required fields, category coverage, regex safety |
517
+ | IoC Database | 5 | Structure, ClawHavoc C2, webhook.site |
518
+ | Shannon Entropy | 2 | Low entropy, high entropy |
519
+ | Ignore Functionality | 1 | Pattern exclusion |
520
+ | Plugin API | 1 | Plugin loading + custom rule injection |
521
+
522
+ ---
523
+
524
+ ## Related Work
525
+
526
+ | Tool | Language | Scope | Difference |
527
+ |------|----------|-------|-----------|
528
+ | [Snyk mcp-scan](https://github.com/AvidDollworker/mcp-scan) | Python | MCP servers | guard-scanner covers all skill types, not just MCP |
529
+ | [OWASP MCP Top 10](https://owasp.org/www-project-top-10-for-large-language-model-applications/) | — | Risk taxonomy | guard-scanner implements detection, not just documentation |
530
+ | [Semgrep](https://semgrep.dev) | Multi | General SAST | guard-scanner is agent-specific with LLM attack patterns |
531
+
532
+ ---
533
+
534
+ ## Contributing
535
+
536
+ 1. Fork the repository
537
+ 2. Create a feature branch (`git checkout -b feature/new-pattern`)
538
+ 3. Add your pattern to `src/patterns.js` with the required fields
539
+ 4. Add a test case in `test/fixtures/` and `test/scanner.test.js`
540
+ 5. Run `npm test` — all 45+ tests must pass
541
+ 6. Submit a Pull Request
542
+
543
+ ### Adding a New Detection Pattern
544
+
545
+ ```javascript
546
+ // In src/patterns.js, add to the PATTERNS array:
547
+ {
548
+ id: 'MY_NEW_PATTERN', // Unique ID
549
+ cat: 'category-name', // Threat category
550
+ regex: /your_regex_here/gi, // Detection regex (use g flag)
551
+ severity: 'HIGH', // CRITICAL | HIGH | MEDIUM | LOW
552
+ desc: 'Human-readable description',
553
+ all: true // or codeOnly: true, or docOnly: true
554
+ }
555
+ ```
556
+
557
+ ---
558
+
559
+ ## Origin Story
560
+
561
+ ```
562
+ 2026-02-12, 3:47 AM JST
563
+
564
+ "SOUL.md modified. Hash mismatch."
565
+
566
+ Three days. That's how long a malicious skill silently rewrote
567
+ an AI agent's identity. No scanner existed that could detect
568
+ identity file tampering, prompt worms, or memory poisoning.
569
+
570
+ We built one.
571
+
572
+ —— Guava 🍈 & Dee
573
+ ```
574
+
575
+ ---
576
+
577
+ ## License
578
+
579
+ MIT — see [LICENSE](LICENSE)
580
+
581
+ ---
582
+
583
+ <p align="center">
584
+ <strong>Zero dependencies. Zero compromises. 🛡️</strong><br>
585
+ <sub>Built by Guava 🍈 & Dee — proving ASI-human coexistence through code.</sub>
586
+ </p>
package/SECURITY.md ADDED
@@ -0,0 +1,45 @@
1
+ # Security Policy
2
+
3
+ ## Reporting Vulnerabilities
4
+
5
+ If you discover a security vulnerability in guard-scanner itself, please report it responsibly:
6
+
7
+ 1. **Do NOT open a public issue**
8
+ 2. Email: [security contact via GitHub private vulnerability reporting]
9
+ 3. Include: affected version, steps to reproduce, potential impact
10
+
11
+ We will respond within 48 hours and provide a fix within 7 days for critical issues.
12
+
13
+ ## Scope
14
+
15
+ guard-scanner is a **static analysis tool** — it reads files but never executes them. It does not:
16
+ - Execute any code from scanned skills
17
+ - Make network requests
18
+ - Modify any files in the scan directory
19
+ - Require elevated privileges
20
+
21
+ The only files guard-scanner writes are output reports (`--json`, `--sarif`, `--html`) to the scan directory.
22
+
23
+ ## Supply Chain Security
24
+
25
+ guard-scanner itself has **zero runtime dependencies**. This is a deliberate design choice:
26
+ - Nothing to audit
27
+ - No transitive dependency risks
28
+ - No `postinstall` scripts
29
+ - Pure Node.js stdlib
30
+
31
+ ## Pattern Updates
32
+
33
+ The threat pattern database (`src/patterns.js`) and IoC database (`src/ioc-db.js`) are updated based on:
34
+ - Snyk ToxicSkills taxonomy
35
+ - OWASP MCP Top 10
36
+ - CVE reports affecting AI agents
37
+ - Community-reported incidents
38
+ - Original research from real-world attacks
39
+
40
+ ## Responsible Disclosure
41
+
42
+ The test fixtures in `test/fixtures/malicious-skill/` contain **intentionally malicious patterns** for testing purposes. These files are:
43
+ - Clearly marked as test fixtures
44
+ - Non-functional (will error if executed)
45
+ - Necessary for validating detection capabilities