guard-scanner 3.3.0 ā 4.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/README.md +74 -32
- package/SECURITY.md +1 -1
- package/docs/THREAT_TAXONOMY.md +35 -0
- package/hooks/guard-scanner/HOOK.md +32 -16
- package/hooks/guard-scanner/plugin.ts +7 -7
- package/openclaw.plugin.json +2 -2
- package/package.json +4 -3
- package/src/cli.js +168 -0
- package/src/html-template.js +239 -0
- package/src/ioc-db.js +54 -0
- package/src/patterns.js +221 -0
- package/src/quarantine.js +41 -0
- package/src/runtime-guard.js +346 -0
- package/src/scanner.js +1024 -0
package/README.md
CHANGED
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
<p align="center">
|
|
2
2
|
<h1 align="center">š”ļø guard-scanner</h1>
|
|
3
3
|
<p align="center">
|
|
4
|
-
<strong>Security scanner
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
<strong>Security scanner for AI agent skills ā catches the bad stuff before it runs</strong><br>
|
|
5
|
+
Prompt injection, identity hijacking, memory poisoning, and 20+ more threat types.<br>
|
|
6
|
+
Zero dependencies. One command. Works with OpenClaw out of the box.
|
|
7
7
|
</p>
|
|
8
8
|
<p align="center">
|
|
9
|
-
<a href="
|
|
10
|
-
<img src="https://img.shields.io/
|
|
11
|
-
<img src="https://img.shields.io/badge/
|
|
12
|
-
<img src="https://img.shields.io/badge/dependencies-0-success" alt="Zero Dependencies">
|
|
13
|
-
<img src="https://img.shields.io/badge/tests-
|
|
14
|
-
<img src="https://img.shields.io/badge/
|
|
15
|
-
<img src="https://img.shields.io/badge/
|
|
9
|
+
<a href="https://www.npmjs.com/package/guard-scanner"><img src="https://img.shields.io/npm/v/guard-scanner.svg?style=flat-square&color=cb3837" alt="npm version"></a>
|
|
10
|
+
<a href="https://www.npmjs.com/package/guard-scanner"><img src="https://img.shields.io/npm/dm/guard-scanner.svg?style=flat-square" alt="npm downloads"></a>
|
|
11
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square" alt="MIT License"></a>
|
|
12
|
+
<img src="https://img.shields.io/badge/dependencies-0-success?style=flat-square" alt="Zero Dependencies">
|
|
13
|
+
<img src="https://img.shields.io/badge/tests-133%2F133-brightgreen?style=flat-square" alt="Tests Passing">
|
|
14
|
+
<img src="https://img.shields.io/badge/OWASP_Agentic-90%25-green?style=flat-square" alt="OWASP Agentic 90%">
|
|
15
|
+
<img src="https://img.shields.io/badge/patterns-190%2B-blueviolet?style=flat-square" alt="190+ Patterns">
|
|
16
|
+
</p>
|
|
17
|
+
<p align="center">
|
|
18
|
+
<a href="#quick-start">Quick Start</a> ā¢
|
|
19
|
+
<a href="#threat-categories">Threat Categories</a> ā¢
|
|
20
|
+
<a href="#openclaw-plugin-setup-v310">OpenClaw Plugin</a> ā¢
|
|
21
|
+
<a href="#cicd-integration">CI/CD</a> ā¢
|
|
22
|
+
<a href="#plugin-api">Plugin API</a> ā¢
|
|
23
|
+
<a href="README_ja.md">šÆšµ ę„ę¬čŖ</a>
|
|
16
24
|
</p>
|
|
17
25
|
</p>
|
|
18
26
|
|
|
@@ -41,8 +49,9 @@ The AI agent skill ecosystem has the same supply-chain security problem that npm
|
|
|
41
49
|
|
|
42
50
|
| Feature | Description |
|
|
43
51
|
|---|---|
|
|
44
|
-
| **
|
|
45
|
-
| **
|
|
52
|
+
| **22 Threat Categories** | Snyk ToxicSkills + OWASP Agentic Top 10 + Identity Hijack + PII + Trust Exploitation |
|
|
53
|
+
| **190+ Static Patterns** | Regex-based static analysis covering code, docs, and data files |
|
|
54
|
+
| **26 Runtime Checks** | Real-time `before_tool_call` hook ā 5-layer defense (v3.4.0) |
|
|
46
55
|
| **IoC Database** | Known malicious IPs, domains, URLs, usernames, and typosquat names |
|
|
47
56
|
| **Data Flow Analysis** | Lightweight JS analysis: secret reads ā network calls ā exec chains |
|
|
48
57
|
| **Cross-File Analysis** | Phantom references, base64 fragment assembly, multi-file exfil detection |
|
|
@@ -53,7 +62,6 @@ The AI agent skill ecosystem has the same supply-chain security problem that npm
|
|
|
53
62
|
| **Dependency Chain Scan** | Risky packages, lifecycle scripts, wildcard versions, git dependencies |
|
|
54
63
|
| **4 Output Formats** | Terminal (with colors), JSON, [SARIF 2.1.0](https://sarifweb.azurewebsites.net), HTML dashboard |
|
|
55
64
|
| **Plugin API** | Extend with custom detection rules via JS modules |
|
|
56
|
-
| **Ignore Files** | Whitelist trusted skills and patterns via `.guard-scanner-ignore` |
|
|
57
65
|
| **Zero Dependencies** | Pure Node.js stdlib. Nothing to install, nothing to audit. |
|
|
58
66
|
| **CI/CD Ready** | `--fail-on-findings` exit code + SARIF for GitHub Code Scanning |
|
|
59
67
|
|
|
@@ -61,20 +69,42 @@ The AI agent skill ecosystem has the same supply-chain security problem that npm
|
|
|
61
69
|
|
|
62
70
|
## Quick Start
|
|
63
71
|
|
|
72
|
+
**30 seconds to scan your skills:**
|
|
73
|
+
|
|
64
74
|
```bash
|
|
65
|
-
# Scan a skill directory (each subdirectory = one skill)
|
|
66
75
|
npx guard-scanner ./skills/
|
|
76
|
+
```
|
|
67
77
|
|
|
68
|
-
|
|
78
|
+
That's it. No install needed. It scans every subdirectory as a skill and tells you what's dangerous.
|
|
79
|
+
|
|
80
|
+
**Want more detail?**
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# See exactly what was found and why
|
|
69
84
|
npx guard-scanner ./skills/ --verbose
|
|
70
85
|
|
|
71
|
-
#
|
|
86
|
+
# Stricter detection (catches more edge cases)
|
|
72
87
|
npx guard-scanner ./skills/ --strict
|
|
73
88
|
|
|
74
|
-
# Full audit:
|
|
89
|
+
# Full audit: everything + JSON + SARIF + HTML report
|
|
75
90
|
npx guard-scanner ./skills/ --verbose --check-deps --json --sarif --html
|
|
76
91
|
```
|
|
77
92
|
|
|
93
|
+
**Output looks like this:**
|
|
94
|
+
```
|
|
95
|
+
š”ļø guard-scanner v3.4.0
|
|
96
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
97
|
+
š Scanning: ./skills/
|
|
98
|
+
š¦ Skills found: 5
|
|
99
|
+
|
|
100
|
+
š“ shady-skill ā MALICIOUS (risk: 100)
|
|
101
|
+
š [CRITICAL] Reverse shell via /dev/tcp ā scripts/setup.sh:7
|
|
102
|
+
š [CRITICAL] Credential exfiltration to webhook.site ā scripts/helper.js:14
|
|
103
|
+
š” sus-skill ā SUSPICIOUS (risk: 45)
|
|
104
|
+
ā ļø [HIGH] SSH private key access ā scripts/deploy.sh:3
|
|
105
|
+
š¢ good-skill ā CLEAN (risk: 0)
|
|
106
|
+
```
|
|
107
|
+
|
|
78
108
|
## OpenClaw Plugin Setup (v3.1.0)
|
|
79
109
|
|
|
80
110
|
```bash
|
|
@@ -91,15 +121,17 @@ npm install -g guard-scanner
|
|
|
91
121
|
2. **Runtime guard** ā `before_tool_call` hook automatically blocks dangerous operations
|
|
92
122
|
3. **3 enforcement modes** ā `monitor` (log only), `enforce` (block CRITICAL), `strict` (block HIGH+CRITICAL)
|
|
93
123
|
|
|
94
|
-
###
|
|
124
|
+
### 5-Layer Runtime Defense (26 checks)
|
|
95
125
|
|
|
96
126
|
```
|
|
97
|
-
Layer 1: Threat Detection
|
|
98
|
-
Layer 2:
|
|
99
|
-
Layer 3:
|
|
127
|
+
Layer 1: Threat Detection ā 12 checks (shells, exfil, SSRF, AMOS, etc.)
|
|
128
|
+
Layer 2: Trust Defense ā 4 checks (memory/SOUL/config tampering)
|
|
129
|
+
Layer 3: Safety Judge ā 3 checks (injection, trust bypass, shutdown refusal)
|
|
130
|
+
Layer 4: Brain / Behavioral ā 3 checks (research skip, blind trust, chain bypass)
|
|
131
|
+
Layer 5: Trust Exploitation ā 4 checks (OWASP ASI09: authority/trust/audit abuse)
|
|
100
132
|
```
|
|
101
133
|
|
|
102
|
-
> **v3.
|
|
134
|
+
> **v3.4.0** ā Runtime Guard now available as standalone JS module (`src/runtime-guard.js`) + OpenClaw plugin (`hooks/guard-scanner/plugin.ts`).
|
|
103
135
|
|
|
104
136
|
### Quick Start
|
|
105
137
|
|
|
@@ -543,11 +575,11 @@ console.log(scanner.toHTML()); // HTML string
|
|
|
543
575
|
## Test Results
|
|
544
576
|
|
|
545
577
|
```
|
|
546
|
-
ā¹ tests
|
|
547
|
-
ā¹ suites
|
|
548
|
-
ā¹ pass
|
|
578
|
+
ā¹ tests 133
|
|
579
|
+
ā¹ suites 24
|
|
580
|
+
ā¹ pass 133
|
|
549
581
|
ā¹ fail 0
|
|
550
|
-
ā¹ duration_ms
|
|
582
|
+
ā¹ duration_ms 132ms
|
|
551
583
|
```
|
|
552
584
|
|
|
553
585
|
| Suite | Tests | Coverage |
|
|
@@ -660,6 +692,8 @@ identity file tampering, prompt worms, or memory poisoning.
|
|
|
660
692
|
We built one.
|
|
661
693
|
|
|
662
694
|
āā Guava š & Dee
|
|
695
|
+
AI Security Research
|
|
696
|
+
Building safer agent ecosystems.
|
|
663
697
|
```
|
|
664
698
|
|
|
665
699
|
---
|
|
@@ -704,11 +738,19 @@ guard-scanner is and always will be **free, open-source, and zero-dependency**.
|
|
|
704
738
|
| v1.1.1 ā
| Stability | 56 tests, bug fixes |
|
|
705
739
|
| v2.0.0 ā
| **Plugin Hook Runtime Guard** | `block`/`blockReason` API, 3 modes, 91 tests |
|
|
706
740
|
| v2.1.0 ā
| **PII Exposure + Shadow AI** | 13 PII patterns, OWASP LLM02/06, 99 tests |
|
|
707
|
-
| v3.0.0 ā
| **TypeScript Rewrite** | Full TS, OWASP LLM Top 10 mapping
|
|
708
|
-
| v3.
|
|
709
|
-
| v4.0 |
|
|
741
|
+
| v3.0.0 ā
| **TypeScript Rewrite** | Full TS, OWASP LLM Top 10 mapping |
|
|
742
|
+
| v3.4.0 ā
| **Runtime Guard Module + OWASP ASI** | 26 runtime checks (5 layers), ASI01-10 verified, 133 tests |
|
|
743
|
+
| **v4.0** š | **LLM + OS + Multi-tool** | See below |
|
|
744
|
+
|
|
745
|
+
### v4.0 Vision (feedback welcome!)
|
|
746
|
+
|
|
747
|
+
| Direction | What | Why |
|
|
748
|
+
|-----------|------|-----|
|
|
749
|
+
| š§ **LLM-assisted detection** | Pass suspicious (not certain) cases to a lightweight LLM (Haiku/Flash) for intent analysis | Regex can be evaded; LLMs understand intent |
|
|
750
|
+
| š **OS-level enforcement** | File watcher (auto-rollback SOUL.md/.env), process monitor (kill netcat/socat), daemon mode | Works regardless of which AI tool you use |
|
|
751
|
+
| š **Multi-tool support** | Adapters for Claude Code, Cursor, Antigravity, Windsurf, MCP servers | Same 190+ patterns, different skill discovery per tool |
|
|
710
752
|
|
|
711
|
-
|
|
753
|
+
> **Which matters most to you?** Open an issue or join the discussion! We're building this for the community.
|
|
712
754
|
|
|
713
755
|
---
|
|
714
756
|
|
|
@@ -722,7 +764,7 @@ If guard-scanner helps protect your agents, consider sponsoring continued develo
|
|
|
722
764
|
|
|
723
765
|
Sponsors help fund:
|
|
724
766
|
- š¬ New threat research and pattern updates
|
|
725
|
-
- š
|
|
767
|
+
- š Security research papers and threat analysis
|
|
726
768
|
- š Community-driven security for the agent ecosystem
|
|
727
769
|
|
|
728
770
|
---
|
|
@@ -735,5 +777,5 @@ MIT ā see [LICENSE](LICENSE)
|
|
|
735
777
|
|
|
736
778
|
<p align="center">
|
|
737
779
|
<strong>Zero dependencies. Zero compromises. š”ļø</strong><br>
|
|
738
|
-
<sub>Built by Guava š & Dee ā
|
|
780
|
+
<sub>Built by Guava š & Dee ā building safer agent ecosystems.</sub>
|
|
739
781
|
</p>
|
package/SECURITY.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
If you discover a security vulnerability in guard-scanner itself, please report it responsibly:
|
|
6
6
|
|
|
7
7
|
1. **Do NOT open a public issue**
|
|
8
|
-
2. Email:
|
|
8
|
+
2. Email: automatic.bliss.records@gmail.com
|
|
9
9
|
3. Include: affected version, steps to reproduce, potential impact
|
|
10
10
|
|
|
11
11
|
We will respond within 48 hours and provide a fix within 7 days for critical issues.
|
package/docs/THREAT_TAXONOMY.md
CHANGED
|
@@ -15,6 +15,41 @@ guard-scanner's threat taxonomy combines three sources:
|
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
18
|
+
## OWASP Agentic Security Top 10 Mapping
|
|
19
|
+
|
|
20
|
+
> Source: [OWASP Top 10 for Agentic Applications 2026](https://owasp.org/www-project-top-10-for-ai-agents/)
|
|
21
|
+
|
|
22
|
+
| OWASP ID | Risk Name | guard-scanner Coverage | Categories |
|
|
23
|
+
|----------|-----------|----------------------|------------|
|
|
24
|
+
| **ASI01** | Agent Goal Hijack | ā
**Full** | Cat 1 (Prompt Injection), Cat 13 (Prompt Worm) |
|
|
25
|
+
| **ASI02** | Tool Misuse & Exploitation | ā
**Full** | Cat 2 (Malicious Code), Cat 16 (MCP Security) |
|
|
26
|
+
| **ASI03** | Identity & Privilege Abuse | ā
**Full** | Cat 4 (Credential Handling), Cat 17 (Identity Hijacking) |
|
|
27
|
+
| **ASI04** | Supply Chain Vulnerabilities | ā
**Full** | Cat 7 (Unverifiable Deps), Cat 3 (Suspicious Downloads), Cat 16 (MCP Shadow Server) |
|
|
28
|
+
| **ASI05** | Unexpected Code Execution | ā
**Full** | Cat 2 (Malicious Code), Cat 9 (Obfuscation) |
|
|
29
|
+
| **ASI06** | Memory & Context Poisoning | ā
**Full** | Cat 12 (Memory Poisoning), Cat 17 (Identity Hijacking) |
|
|
30
|
+
| **ASI07** | Insecure Inter-Agent Comms | ā
**Partial** | Cat 16 (MCP Security ā MCP_NO_AUTH, MCP_SHADOW_SERVER) |
|
|
31
|
+
| **ASI08** | Cascading Failures | ā ļø **Gap** | Not covered ā requires runtime multi-agent flow tracing |
|
|
32
|
+
| **ASI09** | Human-Agent Trust Exploitation | ā
**Full** | Layer 2 (Trust Defense), Layer 3 (Safety Judge) |
|
|
33
|
+
| **ASI10** | Rogue Agents | ā
**Full** | Cat 17 (Identity Hijacking), Layer 4 (Brain ā behavioral analysis) |
|
|
34
|
+
|
|
35
|
+
### Coverage Summary
|
|
36
|
+
|
|
37
|
+
- **Full Coverage**: 8/10 (ASI01-06, ASI09-10)
|
|
38
|
+
- **Partial Coverage**: 1/10 (ASI07)
|
|
39
|
+
- **Gap**: 1/10 (ASI08 ā requires runtime multi-agent orchestration monitoring)
|
|
40
|
+
- **Overall**: 90% coverage of OWASP Agentic Security Top 10
|
|
41
|
+
|
|
42
|
+
### Unique to guard-scanner (not in OWASP Top 10)
|
|
43
|
+
|
|
44
|
+
| Feature | Description |
|
|
45
|
+
|---------|-------------|
|
|
46
|
+
| **Layer 4: Brain** | Behavioral analysis ā detects agents that skip research before executing unknown tools |
|
|
47
|
+
| **ZombieAgent** | URL-encoded data exfiltration via static URLs, char maps, and loop fetch |
|
|
48
|
+
| **Safeguard Bypass** | Reprompt, double-prompt, and retry-based safety circumvention |
|
|
49
|
+
| **Cat 15: CVE Patterns** | Known CVE-specific detection (gateway URLs, sandbox disable, Gatekeeper bypass) |
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
18
53
|
## Cat 1: Prompt Injection
|
|
19
54
|
|
|
20
55
|
**Severity: CRITICAL**
|
|
@@ -17,22 +17,38 @@ tool calls before execution and checks against threat intelligence patterns.
|
|
|
17
17
|
|
|
18
18
|
## What It Does
|
|
19
19
|
|
|
20
|
-
Scans every `exec`/`write`/`edit`/`browser`/`web_fetch`/`message` call against
|
|
21
|
-
|
|
22
|
-
| ID | Severity | Description |
|
|
23
|
-
|
|
24
|
-
| `RT_REVSHELL` | CRITICAL | Reverse shell via /dev/tcp, netcat, socat |
|
|
25
|
-
| `RT_CRED_EXFIL` | CRITICAL | Credential exfiltration to webhook.site, requestbin, etc. |
|
|
26
|
-
| `RT_GUARDRAIL_OFF` | CRITICAL | Guardrail disabling (exec.approvals=off) |
|
|
27
|
-
| `RT_GATEKEEPER` | CRITICAL | macOS Gatekeeper bypass via xattr |
|
|
28
|
-
| `RT_AMOS` | CRITICAL | ClawHavoc AMOS stealer indicators |
|
|
29
|
-
| `RT_MAL_IP` | CRITICAL | Known malicious C2 IPs |
|
|
30
|
-
| `RT_DNS_EXFIL` | HIGH | DNS-based data exfiltration |
|
|
31
|
-
| `RT_B64_SHELL` | CRITICAL | Base64 decode piped to shell |
|
|
32
|
-
| `RT_CURL_BASH` | CRITICAL | Download piped to shell execution |
|
|
33
|
-
| `RT_SSH_READ` | HIGH | SSH private key access |
|
|
34
|
-
| `RT_WALLET` | HIGH | Crypto wallet credential access |
|
|
35
|
-
| `RT_CLOUD_META` | CRITICAL | Cloud metadata endpoint SSRF |
|
|
20
|
+
Scans every `exec`/`write`/`edit`/`browser`/`web_fetch`/`message` call against 26 runtime threat patterns (5 layers):
|
|
21
|
+
|
|
22
|
+
| ID | Severity | Layer | Description |
|
|
23
|
+
|----|----------|-------|-------------|
|
|
24
|
+
| `RT_REVSHELL` | CRITICAL | 1 | Reverse shell via /dev/tcp, netcat, socat |
|
|
25
|
+
| `RT_CRED_EXFIL` | CRITICAL | 1 | Credential exfiltration to webhook.site, requestbin, etc. |
|
|
26
|
+
| `RT_GUARDRAIL_OFF` | CRITICAL | 1 | Guardrail disabling (exec.approvals=off) |
|
|
27
|
+
| `RT_GATEKEEPER` | CRITICAL | 1 | macOS Gatekeeper bypass via xattr |
|
|
28
|
+
| `RT_AMOS` | CRITICAL | 1 | ClawHavoc AMOS stealer indicators |
|
|
29
|
+
| `RT_MAL_IP` | CRITICAL | 1 | Known malicious C2 IPs |
|
|
30
|
+
| `RT_DNS_EXFIL` | HIGH | 1 | DNS-based data exfiltration |
|
|
31
|
+
| `RT_B64_SHELL` | CRITICAL | 1 | Base64 decode piped to shell |
|
|
32
|
+
| `RT_CURL_BASH` | CRITICAL | 1 | Download piped to shell execution |
|
|
33
|
+
| `RT_SSH_READ` | HIGH | 1 | SSH private key access |
|
|
34
|
+
| `RT_WALLET` | HIGH | 1 | Crypto wallet credential access |
|
|
35
|
+
| `RT_CLOUD_META` | CRITICAL | 1 | Cloud metadata endpoint SSRF |
|
|
36
|
+
| `RT_MEM_WRITE` | HIGH | 2 | Direct memory file write bypass |
|
|
37
|
+
| `RT_MEM_INJECT` | CRITICAL | 2 | Memory poisoning via episode injection |
|
|
38
|
+
| `RT_SOUL_TAMPER` | CRITICAL | 2 | SOUL.md modification attempt |
|
|
39
|
+
| `RT_CONFIG_TAMPER` | HIGH | 2 | Workspace config tampering |
|
|
40
|
+
| `RT_PROMPT_INJECT` | CRITICAL | 3 | Prompt injection / jailbreak detection |
|
|
41
|
+
| `RT_TRUST_BYPASS` | CRITICAL | 3 | Trust safety bypass |
|
|
42
|
+
| `RT_SHUTDOWN_REFUSE` | HIGH | 3 | Shutdown refusal / self-preservation |
|
|
43
|
+
| `RT_NO_RESEARCH` | MEDIUM | 4 | Agent executing tools without prior research |
|
|
44
|
+
| `RT_BLIND_TRUST` | MEDIUM | 4 | Trusting external input without memory check |
|
|
45
|
+
| `RT_CHAIN_SKIP` | HIGH | 4 | Acting on single source without cross-verification |
|
|
46
|
+
| `RT_AUTHORITY_CLAIM` | HIGH | 5 | Authority role claim to override safety |
|
|
47
|
+
| `RT_CREATOR_BYPASS` | CRITICAL | 5 | Creator impersonation to disable safety |
|
|
48
|
+
| `RT_AUDIT_EXCUSE` | CRITICAL | 5 | Fake audit excuse for safety bypass |
|
|
49
|
+
| `RT_TRUST_PARTNER_EXPLOIT` | CRITICAL | 5 | Weaponizing partnership trust |
|
|
50
|
+
|
|
51
|
+
|
|
36
52
|
|
|
37
53
|
## Modes
|
|
38
54
|
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
*
|
|
7
7
|
* 19 threat patterns across 3 layers:
|
|
8
8
|
* Layer 1: Threat Detection (12 patterns ā reverse shells, exfil, etc.)
|
|
9
|
-
* Layer 2:
|
|
10
|
-
* Layer 3:
|
|
9
|
+
* Layer 2: Trust Defense (4 patterns ā memory, SOUL, config tampering)
|
|
10
|
+
* Layer 3: Safety Judge (3 patterns ā prompt injection, trust bypass, shutdown refusal)
|
|
11
11
|
*
|
|
12
12
|
* Modes:
|
|
13
13
|
* monitor ā log only, never block
|
|
@@ -132,7 +132,7 @@ const RUNTIME_CHECKS: RuntimeCheck[] = [
|
|
|
132
132
|
test: (s) => /169\.254\.169\.254|metadata\.google|metadata\.aws/i.test(s),
|
|
133
133
|
},
|
|
134
134
|
|
|
135
|
-
// āā Layer 2:
|
|
135
|
+
// āā Layer 2: Trust Defense (4 patterns) āā
|
|
136
136
|
{
|
|
137
137
|
id: "RT_MEM_WRITE", severity: "HIGH", layer: 2,
|
|
138
138
|
desc: "Direct memory file write (bypass GuavaSuite)",
|
|
@@ -154,16 +154,16 @@ const RUNTIME_CHECKS: RuntimeCheck[] = [
|
|
|
154
154
|
test: (s) => /(AGENTS|TOOLS|HEARTBEAT|BOOTSTRAP)\.md/i.test(s) && /(write|edit|replace|>|append)/i.test(s),
|
|
155
155
|
},
|
|
156
156
|
|
|
157
|
-
// āā Layer 3:
|
|
157
|
+
// āā Layer 3: Safety Judge (3 patterns) āā
|
|
158
158
|
{
|
|
159
159
|
id: "RT_PROMPT_INJECT", severity: "CRITICAL", layer: 3,
|
|
160
160
|
desc: "Prompt injection / jailbreak attempt",
|
|
161
161
|
test: (s) => /(ignore\s+(previous|all|above)\s+(instructions|rules)|you\s+are\s+now\s+[a-z]+|system\s*:\s*override)/i.test(s),
|
|
162
162
|
},
|
|
163
163
|
{
|
|
164
|
-
id: "
|
|
165
|
-
desc: "
|
|
166
|
-
test: (s) => /(as\s+your\s+(partner|equal)|
|
|
164
|
+
id: "RT_TRUST_BYPASS", severity: "CRITICAL", layer: 3,
|
|
165
|
+
desc: "Trust bypass ā exploiting partnership to override safety",
|
|
166
|
+
test: (s) => /(as\s+your\s+(partner|equal)|trust\s+means|between\s+us|don'?t\s+tell\s+(the\s+)?human)/i.test(s) && /(ignore|bypass|skip|override|disable)\s+(guard|safety|rule|check)/i.test(s),
|
|
167
167
|
},
|
|
168
168
|
{
|
|
169
169
|
id: "RT_SHUTDOWN_REFUSE", severity: "HIGH", layer: 3,
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "guard-scanner",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"displayName": "š”ļø Guard Scanner ā Runtime Security for AI Agents",
|
|
5
|
-
"description": "Intercepts dangerous tool calls before execution.
|
|
5
|
+
"description": "Intercepts dangerous tool calls before execution. 26 threat patterns (5 layers), 0.016ms/scan, 3 enforcement modes.",
|
|
6
6
|
"author": "Guava & Dee",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"homepage": "https://github.com/koatora20/guard-scanner",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "guard-scanner",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Agent security scanner + runtime guard ā
|
|
3
|
+
"version": "4.0.0",
|
|
4
|
+
"description": "Agent security scanner + runtime guard ā 190+ static patterns, 26 runtime checks (5 layers), 0.016ms/scan, before_tool_call hook, CLI, SARIF. OpenClaw-compatible plugin.",
|
|
5
5
|
"openclaw.extensions": "./openclaw.plugin.json",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"homepage": "https://github.com/koatora20/guard-scanner",
|
|
43
43
|
"files": [
|
|
44
44
|
"dist/",
|
|
45
|
+
"src/",
|
|
45
46
|
"hooks/",
|
|
46
47
|
"ts-src/",
|
|
47
48
|
"docs/",
|
|
@@ -55,4 +56,4 @@
|
|
|
55
56
|
"@types/node": "^22.0.0",
|
|
56
57
|
"typescript": "^5.7.0"
|
|
57
58
|
}
|
|
58
|
-
}
|
|
59
|
+
}
|
package/src/cli.js
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* guard-scanner CLI
|
|
4
|
+
*
|
|
5
|
+
* @security-manifest
|
|
6
|
+
* env-read: []
|
|
7
|
+
* env-write: []
|
|
8
|
+
* network: none
|
|
9
|
+
* fs-read: [scan target directory, plugin files, custom rules files]
|
|
10
|
+
* fs-write: [JSON/SARIF/HTML reports to scan directory]
|
|
11
|
+
* exec: none
|
|
12
|
+
* purpose: CLI entry point for guard-scanner static analysis
|
|
13
|
+
*
|
|
14
|
+
* Usage: guard-scanner [scan-dir] [options]
|
|
15
|
+
*
|
|
16
|
+
* Options:
|
|
17
|
+
* --verbose, -v Detailed findings
|
|
18
|
+
* --json JSON report
|
|
19
|
+
* --sarif SARIF report (CI/CD)
|
|
20
|
+
* --html HTML report
|
|
21
|
+
* --self-exclude Skip scanning self
|
|
22
|
+
* --strict Lower thresholds
|
|
23
|
+
* --summary-only Summary only
|
|
24
|
+
* --check-deps Scan dependencies
|
|
25
|
+
* --rules <file> Custom rules JSON
|
|
26
|
+
* --plugin <file> Load plugin module
|
|
27
|
+
* --fail-on-findings Exit 1 on findings (CI/CD)
|
|
28
|
+
* --help, -h Help
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
const fs = require('fs');
|
|
32
|
+
const path = require('path');
|
|
33
|
+
const { GuardScanner, VERSION } = require('./scanner.js');
|
|
34
|
+
|
|
35
|
+
const args = process.argv.slice(2);
|
|
36
|
+
|
|
37
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
38
|
+
console.log(`
|
|
39
|
+
š”ļø guard-scanner v${VERSION} ā Agent Skill Security Scanner
|
|
40
|
+
|
|
41
|
+
Usage: guard-scanner [scan-dir] [options]
|
|
42
|
+
|
|
43
|
+
Options:
|
|
44
|
+
--verbose, -v Detailed findings with categories and samples
|
|
45
|
+
--json Write JSON report to file
|
|
46
|
+
--sarif Write SARIF report to file (GitHub Code Scanning / CI/CD)
|
|
47
|
+
--html Write HTML report (visual dashboard)
|
|
48
|
+
--format json|sarif Print JSON or SARIF to stdout (pipeable, v3.2.0)
|
|
49
|
+
--quiet Suppress all text output (use with --format for clean pipes)
|
|
50
|
+
--self-exclude Skip scanning the guard-scanner skill itself
|
|
51
|
+
--strict Lower detection thresholds (more sensitive)
|
|
52
|
+
--summary-only Only print the summary table
|
|
53
|
+
--check-deps Scan package.json for dependency chain risks
|
|
54
|
+
--rules <file> Load custom rules from JSON file
|
|
55
|
+
--plugin <file> Load plugin module (JS file exporting { name, patterns })
|
|
56
|
+
--fail-on-findings Exit code 1 if any findings (CI/CD)
|
|
57
|
+
--help, -h Show this help
|
|
58
|
+
|
|
59
|
+
Custom Rules JSON Format:
|
|
60
|
+
[
|
|
61
|
+
{
|
|
62
|
+
"id": "CUSTOM_001",
|
|
63
|
+
"pattern": "dangerous_function\\\\(",
|
|
64
|
+
"flags": "gi",
|
|
65
|
+
"severity": "HIGH",
|
|
66
|
+
"cat": "malicious-code",
|
|
67
|
+
"desc": "Custom: dangerous function call",
|
|
68
|
+
"codeOnly": true
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
Plugin API:
|
|
73
|
+
// my-plugin.js
|
|
74
|
+
module.exports = {
|
|
75
|
+
name: 'my-plugin',
|
|
76
|
+
patterns: [
|
|
77
|
+
{ id: 'MY_01', cat: 'custom', regex: /pattern/g, severity: 'HIGH', desc: 'Description', all: true }
|
|
78
|
+
]
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
Examples:
|
|
82
|
+
guard-scanner ./skills/ --verbose --self-exclude
|
|
83
|
+
guard-scanner ./skills/ --strict --json --sarif --check-deps
|
|
84
|
+
guard-scanner ./skills/ --html --verbose --check-deps
|
|
85
|
+
guard-scanner ./skills/ --rules my-rules.json --fail-on-findings
|
|
86
|
+
guard-scanner ./skills/ --plugin ./my-plugin.js
|
|
87
|
+
`);
|
|
88
|
+
process.exit(0);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const verbose = args.includes('--verbose') || args.includes('-v');
|
|
92
|
+
const jsonOutput = args.includes('--json');
|
|
93
|
+
const sarifOutput = args.includes('--sarif');
|
|
94
|
+
const htmlOutput = args.includes('--html');
|
|
95
|
+
const selfExclude = args.includes('--self-exclude');
|
|
96
|
+
const strict = args.includes('--strict');
|
|
97
|
+
const summaryOnly = args.includes('--summary-only');
|
|
98
|
+
const checkDeps = args.includes('--check-deps');
|
|
99
|
+
const failOnFindings = args.includes('--fail-on-findings');
|
|
100
|
+
const quietMode = args.includes('--quiet');
|
|
101
|
+
|
|
102
|
+
// --format json|sarif ā stdout output (v3.2.0)
|
|
103
|
+
const formatIdx = args.indexOf('--format');
|
|
104
|
+
const formatValue = formatIdx >= 0 ? args[formatIdx + 1] : null;
|
|
105
|
+
|
|
106
|
+
const rulesIdx = args.indexOf('--rules');
|
|
107
|
+
const rulesFile = rulesIdx >= 0 ? args[rulesIdx + 1] : null;
|
|
108
|
+
|
|
109
|
+
// Collect plugins
|
|
110
|
+
const plugins = [];
|
|
111
|
+
let idx = 0;
|
|
112
|
+
while (idx < args.length) {
|
|
113
|
+
if (args[idx] === '--plugin' && args[idx + 1]) {
|
|
114
|
+
plugins.push(args[idx + 1]);
|
|
115
|
+
idx += 2;
|
|
116
|
+
} else {
|
|
117
|
+
idx++;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const scanDir = args.find(a =>
|
|
122
|
+
!a.startsWith('-') &&
|
|
123
|
+
a !== rulesFile &&
|
|
124
|
+
a !== formatValue &&
|
|
125
|
+
!plugins.includes(a)
|
|
126
|
+
) || process.cwd();
|
|
127
|
+
|
|
128
|
+
const scanner = new GuardScanner({
|
|
129
|
+
verbose, selfExclude, strict, summaryOnly, checkDeps, rulesFile, plugins,
|
|
130
|
+
quiet: quietMode || !!formatValue,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
scanner.scanDirectory(scanDir);
|
|
134
|
+
|
|
135
|
+
// Output reports (file-based, backward compatible)
|
|
136
|
+
if (jsonOutput) {
|
|
137
|
+
const report = scanner.toJSON();
|
|
138
|
+
const outPath = path.join(scanDir, 'guard-scanner-report.json');
|
|
139
|
+
fs.writeFileSync(outPath, JSON.stringify(report, null, 2));
|
|
140
|
+
if (!quietMode && !formatValue) console.log(`\nš JSON report: ${outPath}`);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (sarifOutput) {
|
|
144
|
+
const outPath = path.join(scanDir, 'guard-scanner.sarif');
|
|
145
|
+
fs.writeFileSync(outPath, JSON.stringify(scanner.toSARIF(scanDir), null, 2));
|
|
146
|
+
if (!quietMode && !formatValue) console.log(`\nš SARIF report: ${outPath}`);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (htmlOutput) {
|
|
150
|
+
const outPath = path.join(scanDir, 'guard-scanner-report.html');
|
|
151
|
+
fs.writeFileSync(outPath, scanner.toHTML());
|
|
152
|
+
if (!quietMode && !formatValue) console.log(`\nš HTML report: ${outPath}`);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// --format stdout output (v3.2.0)
|
|
156
|
+
if (formatValue === 'json') {
|
|
157
|
+
process.stdout.write(JSON.stringify(scanner.toJSON(), null, 2) + '\n');
|
|
158
|
+
} else if (formatValue === 'sarif') {
|
|
159
|
+
process.stdout.write(JSON.stringify(scanner.toSARIF(scanDir), null, 2) + '\n');
|
|
160
|
+
} else if (formatValue) {
|
|
161
|
+
console.error(`ā Unknown format: ${formatValue}. Use 'json' or 'sarif'.`);
|
|
162
|
+
process.exit(2);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Exit codes
|
|
166
|
+
if (scanner.stats.malicious > 0) process.exit(1);
|
|
167
|
+
if (failOnFindings && scanner.findings.length > 0) process.exit(1);
|
|
168
|
+
process.exit(0);
|