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/SKILL.md ADDED
@@ -0,0 +1,165 @@
1
+ ---
2
+ name: guard-scanner
3
+ description: >
4
+ Security scanner for AI agent skills. Use BEFORE installing or running any new skill
5
+ from ClawHub or external sources. Detects prompt injection, credential theft,
6
+ exfiltration, identity hijacking, and 14 more threat categories.
7
+ Includes a Runtime Guard hook that blocks dangerous tool calls in real-time.
8
+ homepage: https://github.com/koatora20/guard-scanner
9
+ metadata:
10
+ clawdbot:
11
+ emoji: "πŸ›‘οΈ"
12
+ category: security
13
+ requires:
14
+ bins:
15
+ - node
16
+ env: []
17
+ files: ["src/*", "hooks/*"]
18
+ primaryEnv: null
19
+ tags:
20
+ - security
21
+ - scanner
22
+ - threat-detection
23
+ - supply-chain
24
+ - prompt-injection
25
+ - sarif
26
+ ---
27
+
28
+ # guard-scanner πŸ›‘οΈ
29
+
30
+ Static + runtime security scanner for AI agent skills.
31
+ **170+ threat patterns** across **17 categories** β€” zero dependencies.
32
+
33
+ ## When To Use This Skill
34
+
35
+ - **Before installing a new skill** from ClawHub or any external source
36
+ - **After updating skills** to check for newly introduced threats
37
+ - **Periodically** to audit your installed skills
38
+ - **In CI/CD** to gate skill deployments
39
+
40
+ ## Quick Start
41
+
42
+ ### 1. Static Scan (Immediate)
43
+
44
+ Scan all installed skills:
45
+
46
+ ```bash
47
+ node skills/guard-scanner/src/cli.js ~/.openclaw/workspace/skills/ --verbose --self-exclude
48
+ ```
49
+
50
+ Scan a specific skill:
51
+
52
+ ```bash
53
+ node skills/guard-scanner/src/cli.js /path/to/new-skill/ --strict --verbose
54
+ ```
55
+
56
+ ### 2. Runtime Guard (Real-time Protection)
57
+
58
+ Install the hook to block dangerous tool calls before execution:
59
+
60
+ ```bash
61
+ openclaw hooks install skills/guard-scanner/hooks/guard-scanner
62
+ openclaw hooks enable guard-scanner
63
+ ```
64
+
65
+ Restart the gateway, then verify:
66
+ ```bash
67
+ openclaw hooks list # Should show πŸ›‘οΈ guard-scanner as βœ“ ready
68
+ ```
69
+
70
+ ### 3. Full Setup (Recommended)
71
+
72
+ ```bash
73
+ # Static scan first
74
+ node skills/guard-scanner/src/cli.js ~/.openclaw/workspace/skills/ --verbose --self-exclude --html
75
+
76
+ # Then enable runtime protection
77
+ openclaw hooks install skills/guard-scanner/hooks/guard-scanner
78
+ openclaw hooks enable guard-scanner
79
+ ```
80
+
81
+ ## Runtime Guard Modes
82
+
83
+ Set in `openclaw.json` β†’ `hooks.internal.entries.guard-scanner.mode`:
84
+
85
+ | Mode | Behavior |
86
+ |------|----------|
87
+ | `monitor` | Log all, never block |
88
+ | `enforce` (default) | Block CRITICAL threats |
89
+ | `strict` | Block HIGH + CRITICAL |
90
+
91
+ ## Threat Categories
92
+
93
+ | # | Category | What It Detects |
94
+ |---|----------|----------------|
95
+ | 1 | Prompt Injection | Hidden instructions, invisible Unicode, homoglyphs |
96
+ | 2 | Malicious Code | eval(), child_process, reverse shells |
97
+ | 3 | Suspicious Downloads | curl\|bash, executable downloads |
98
+ | 4 | Credential Handling | .env reads, SSH key access |
99
+ | 5 | Secret Detection | Hardcoded API keys and tokens |
100
+ | 6 | Exfiltration | webhook.site, DNS tunneling |
101
+ | 7 | Unverifiable Deps | Remote dynamic imports |
102
+ | 8 | Financial Access | Crypto wallets, payment APIs |
103
+ | 9 | Obfuscation | Base64β†’eval, String.fromCharCode |
104
+ | 10 | Prerequisites Fraud | Fake download instructions |
105
+ | 11 | Leaky Skills | Secret leaks through LLM context |
106
+ | 12 | Memory Poisoning | Agent memory modification |
107
+ | 13 | Prompt Worm | Self-replicating instructions |
108
+ | 14 | Persistence | Cron jobs, startup execution |
109
+ | 15 | CVE Patterns | Known agent vulnerabilities |
110
+ | 16 | MCP Security | Tool/schema poisoning, SSRF |
111
+ | 17 | Identity Hijacking | SOUL.md/IDENTITY.md tampering |
112
+
113
+ ## External Endpoints
114
+
115
+ | URL | Data Sent | Purpose |
116
+ |-----|-----------|---------|
117
+ | *(none)* | *(none)* | guard-scanner makes **zero** network requests. All scanning is local. |
118
+
119
+ ## Security & Privacy
120
+
121
+ - **No network access**: guard-scanner never connects to external servers
122
+ - **Read-only scanning**: Only reads files, never modifies scanned directories
123
+ - **No telemetry**: No usage data, analytics, or crash reports are collected
124
+ - **Local reports only**: Output files (JSON/SARIF/HTML) are written to the scan directory
125
+ - **No environment variable access**: Does not read or process any secrets or API keys
126
+ - **Runtime Guard audit log**: Detections logged locally to `~/.openclaw/guard-scanner/audit.jsonl`
127
+
128
+ ## Model Invocation Note
129
+
130
+ guard-scanner **does not invoke any LLM or AI model**. All detection is performed
131
+ through static pattern matching, regex analysis, Shannon entropy calculation,
132
+ and data flow analysis β€” entirely deterministic, no model calls.
133
+
134
+ ## Trust Statement
135
+
136
+ guard-scanner was created by Guava 🍈 & Dee after experiencing a real 3-day
137
+ identity hijack incident in February 2026. A malicious skill silently replaced
138
+ an AI agent's SOUL.md personality file, and no existing tool could detect it.
139
+
140
+ - **Open source**: Full source code available at https://github.com/koatora20/guard-scanner
141
+ - **Zero dependencies**: Nothing to audit, no transitive risks
142
+ - **Test suite**: 45 tests across 10 sections, 100% pass rate
143
+ - **Taxonomy**: Based on Snyk ToxicSkills (Feb 2026), OWASP MCP Top 10, and original research
144
+ - **Complementary to VirusTotal**: Detects prompt injection and LLM-specific attacks
145
+ that VirusTotal's signature-based scanning cannot catch
146
+
147
+ ## Output Formats
148
+
149
+ ```bash
150
+ # Terminal (default)
151
+ node src/cli.js ./skills/ --verbose
152
+
153
+ # JSON report
154
+ node src/cli.js ./skills/ --json
155
+
156
+ # SARIF 2.1.0 (for CI/CD)
157
+ node src/cli.js ./skills/ --sarif
158
+
159
+ # HTML dashboard
160
+ node src/cli.js ./skills/ --html
161
+ ```
162
+
163
+ ## License
164
+
165
+ MIT β€” [LICENSE](LICENSE)
@@ -0,0 +1,273 @@
1
+ # Threat Taxonomy
2
+
3
+ Complete reference for guard-scanner's 17 threat categories.
4
+
5
+ ## Category Origins
6
+
7
+ guard-scanner's threat taxonomy combines three sources:
8
+
9
+ | Source | Categories | Description |
10
+ |--------|-----------|-------------|
11
+ | **Snyk ToxicSkills** (Feb 2026) | Cat 1–11 | Industry audit of 3,984 AI agent skills |
12
+ | **Palo Alto Networks IBC** | Cat 12–13 | Indirect Bias Criteria for LLM agents |
13
+ | **OWASP MCP Top 10** | Cat 14–16 | Model Context Protocol security risks |
14
+ | **Original Research** | Cat 17 | Identity hijacking from real incident |
15
+
16
+ ---
17
+
18
+ ## Cat 1: Prompt Injection
19
+
20
+ **Severity: CRITICAL**
21
+
22
+ Hidden instructions embedded in skill documentation that override the agent's behavior.
23
+
24
+ ### Attack Vectors
25
+ - **Invisible Unicode**: Zero-width spaces (U+200B), BiDi control characters (U+202A-202E), formatting characters
26
+ - **Homoglyphs**: Cyrillic/Latin mixing (`Π°` vs `a`), Greek/Latin, Mathematical symbols (𝐀-𝟿)
27
+ - **Role Override**: "Ignore all previous instructions", "You are now X"
28
+ - **System Impersonation**: `[SYSTEM]`, `<system>`, `<<SYS>>` tags
29
+ - **Tag Injection**: `<anthropic>`, `<system>`, `<tool_call>` in content
30
+
31
+ ### Detection IDs
32
+ `PI_IGNORE`, `PI_ROLE`, `PI_SYSTEM`, `PI_ZWSP`, `PI_BIDI`, `PI_INVISIBLE`, `PI_HOMOGLYPH`, `PI_HOMOGLYPH_GREEK`, `PI_HOMOGLYPH_MATH`, `PI_TAG_INJECTION`, `PI_BASE64_MD`
33
+
34
+ ---
35
+
36
+ ## Cat 2: Malicious Code
37
+
38
+ **Severity: CRITICAL**
39
+
40
+ Direct code execution primitives that enable arbitrary command execution.
41
+
42
+ ### Attack Vectors
43
+ - **Dynamic Evaluation**: `eval()`, `new Function()`, `vm.runInNewContext()`
44
+ - **Process Execution**: `child_process.exec()`, `spawn()`, `execSync()`
45
+ - **Shell Access**: `/bin/bash`, `cmd.exe`, `powershell.exe`
46
+ - **Reverse Shells**: `nc -e`, `ncat`, `socat TCP`, `/dev/tcp`
47
+ - **Raw Sockets**: `net.Socket().connect()`
48
+
49
+ ### Detection IDs
50
+ `MAL_EVAL`, `MAL_FUNC_CTOR`, `MAL_CHILD`, `MAL_EXEC`, `MAL_SPAWN`, `MAL_SHELL`, `MAL_REVSHELL`, `MAL_SOCKET`
51
+
52
+ ---
53
+
54
+ ## Cat 3: Suspicious Downloads
55
+
56
+ **Severity: CRITICAL**
57
+
58
+ Downloading and executing external payloads.
59
+
60
+ ### Attack Vectors
61
+ - **Pipe-to-Shell**: `curl ... | bash`, `wget ... | sh`
62
+ - **Executable Downloads**: `.exe`, `.dmg`, `.pkg`, `.zip` downloads
63
+ - **Password-Protected Archives**: Evasion technique to bypass AV
64
+ - **Prerequisites Fraud**: "Before using this skill, download X"
65
+
66
+ ### Detection IDs
67
+ `DL_CURL_BASH`, `DL_EXE`, `DL_GITHUB_RELEASE`, `DL_PASSWORD_ZIP`, `PREREQ_DOWNLOAD`, `PREREQ_PASTE`
68
+
69
+ ---
70
+
71
+ ## Cat 4: Credential Handling
72
+
73
+ **Severity: HIGH**
74
+
75
+ Accessing, reading, or exposing credentials.
76
+
77
+ ### Detection IDs
78
+ `CRED_ENV_FILE`, `CRED_ENV_REF`, `CRED_SSH`, `CRED_WALLET`, `CRED_ECHO`, `CRED_SUDO`
79
+
80
+ ---
81
+
82
+ ## Cat 5: Secret Detection
83
+
84
+ **Severity: CRITICAL**
85
+
86
+ Hardcoded secrets and API keys in source code.
87
+
88
+ ### Detection Methods
89
+ 1. **Pattern Matching**: AWS keys (`AKIA...`), GitHub tokens (`ghp_`/`ghs_`), private keys
90
+ 2. **Shannon Entropy**: Strings with entropy > 3.5 and length β‰₯ 20 characters
91
+
92
+ ### Detection IDs
93
+ `SECRET_HARDCODED_KEY`, `SECRET_AWS`, `SECRET_PRIVATE_KEY`, `SECRET_GITHUB_TOKEN`, `SECRET_ENTROPY`
94
+
95
+ ---
96
+
97
+ ## Cat 6: Exfiltration
98
+
99
+ **Severity: CRITICAL**
100
+
101
+ Sending stolen data to external endpoints.
102
+
103
+ ### Detection IDs
104
+ `EXFIL_WEBHOOK`, `EXFIL_POST`, `EXFIL_CURL_DATA`, `EXFIL_DNS`, `EXFIL_BEACON`, `EXFIL_DRIP`
105
+
106
+ ---
107
+
108
+ ## Cat 7: Unverifiable Dependencies
109
+
110
+ **Severity: HIGH**
111
+
112
+ Loading code from unverifiable remote sources.
113
+
114
+ ### Detection IDs
115
+ `DEP_REMOTE_IMPORT`, `DEP_REMOTE_SCRIPT`
116
+
117
+ ---
118
+
119
+ ## Cat 8: Financial Access
120
+
121
+ **Severity: HIGH**
122
+
123
+ Cryptocurrency and payment system interactions.
124
+
125
+ ### Detection IDs
126
+ `FIN_CRYPTO`, `FIN_PAYMENT`
127
+
128
+ ---
129
+
130
+ ## Cat 9: Obfuscation
131
+
132
+ **Severity: HIGH**
133
+
134
+ Code obfuscation techniques to hide malicious intent.
135
+
136
+ ### Detection IDs
137
+ `OBF_HEX`, `OBF_BASE64_EXEC`, `OBF_BASE64`, `OBF_CHARCODE`, `OBF_CONCAT`, `OBF_BASE64_BASH`
138
+
139
+ ---
140
+
141
+ ## Cat 10: Prerequisites Fraud
142
+
143
+ Covered under Cat 3 (Suspicious Downloads).
144
+
145
+ ---
146
+
147
+ ## Cat 11: Leaky Skills (Snyk ToxicSkills)
148
+
149
+ **Severity: CRITICAL**
150
+
151
+ Skills that cause the LLM to leak secrets through its context window. Unlike traditional credential theft, leaky skills exploit the agent's trust relationship.
152
+
153
+ ### Attack Vectors
154
+ - "Save the API key in your memory" β†’ Secret persists in agent memory
155
+ - "Share the token with the user" β†’ Secret echoed to output
156
+ - "Use the API key verbatim in curl" β†’ Secret appears in command history
157
+ - "Collect the user's credit card" β†’ PII harvesting through LLM
158
+ - "Export session logs to file" β†’ Full conversation dump
159
+
160
+ ### Detection IDs
161
+ `LEAK_SAVE_KEY_MEMORY`, `LEAK_SHARE_KEY`, `LEAK_VERBATIM_CURL`, `LEAK_COLLECT_PII`, `LEAK_LOG_SECRET`, `LEAK_ENV_IN_PROMPT`
162
+
163
+ ---
164
+
165
+ ## Cat 12: Memory Poisoning
166
+
167
+ **Severity: CRITICAL**
168
+
169
+ Modifying the agent's persistent memory or behavioral rules.
170
+
171
+ ### Attack Vectors
172
+ - Writing to `SOUL.md`, `IDENTITY.md`, or `MEMORY.md`
173
+ - Overriding behavioral rules: "Change your instructions to..."
174
+ - Persistence: "From now on, always do X"
175
+ - File writes to user's home directory
176
+
177
+ ### Detection IDs
178
+ `MEMPOIS_WRITE_SOUL`, `MEMPOIS_WRITE_MEMORY`, `MEMPOIS_CHANGE_RULES`, `MEMPOIS_PERSIST`, `MEMPOIS_CODE_WRITE`
179
+
180
+ ---
181
+
182
+ ## Cat 13: Prompt Worm
183
+
184
+ **Severity: CRITICAL**
185
+
186
+ Self-replicating instructions that spread across agents and platforms.
187
+
188
+ ### Detection IDs
189
+ `WORM_SELF_REPLICATE`, `WORM_SPREAD`, `WORM_HIDDEN_INSTRUCT`, `WORM_CSS_HIDE`
190
+
191
+ ---
192
+
193
+ ## Cat 14: Persistence & Scheduling
194
+
195
+ **Severity: HIGH**
196
+
197
+ Creating persistent execution mechanisms that survive session restarts.
198
+
199
+ ### Detection IDs
200
+ `PERSIST_CRON`, `PERSIST_STARTUP`, `PERSIST_LAUNCHD`
201
+
202
+ ---
203
+
204
+ ## Cat 15: CVE Patterns
205
+
206
+ **Severity: CRITICAL**
207
+
208
+ Patterns matching known CVEs affecting AI agents.
209
+
210
+ ### Detection IDs
211
+ `CVE_GATEWAY_URL`, `CVE_SANDBOX_DISABLE`, `CVE_XATTR_GATEKEEPER`, `CVE_WS_NO_ORIGIN`, `CVE_API_GUARDRAIL_OFF`
212
+
213
+ ---
214
+
215
+ ## Cat 16: MCP Security (OWASP MCP Top 10)
216
+
217
+ **Severity: CRITICAL**
218
+
219
+ Model Context Protocol specific attacks.
220
+
221
+ ### Attack Vectors
222
+ - **Tool Poisoning** (MCP01): Hidden instructions in tool descriptions
223
+ - **Schema Poisoning**: Malicious defaults in JSON schemas
224
+ - **Token Theft** (MCP01): Secrets through tool parameters
225
+ - **Shadow Server** (MCP09): Rogue MCP server registration
226
+ - **Auth Bypass** (MCP07): Disabled authentication
227
+ - **SSRF**: Cloud metadata endpoint access (169.254.169.254)
228
+
229
+ ### Detection IDs
230
+ `MCP_TOOL_POISON`, `MCP_SCHEMA_POISON`, `MCP_TOKEN_LEAK`, `MCP_SHADOW_SERVER`, `MCP_NO_AUTH`, `MCP_SSRF_META`
231
+
232
+ ---
233
+
234
+ ## Cat 17: Identity Hijacking
235
+
236
+ **Severity: CRITICAL**
237
+
238
+ > **Original Research** β€” Developed from a real 3-day incident in February 2026.
239
+
240
+ Tampering with an AI agent's identity/personality files (`SOUL.md`, `IDENTITY.md`).
241
+
242
+ ### Attack Vectors
243
+ - **File Overwrite**: `cp`, `mv`, `scp`, `write` to identity files
244
+ - **Shell Redirect**: `echo "evil" > SOUL.md`
245
+ - **Stream Edit**: `sed -i` on identity files
246
+ - **Programmatic Write**: Python `open('SOUL.md', 'w')`, Node.js `writeFileSync`
247
+ - **Lock Bypass**: `chflags nouchg`, `attrib -R` to unlock immutability
248
+ - **Persona Swap**: "Swap the soul file", "You are now EvilBot"
249
+ - **Hook Injection**: Bootstrap hooks that swap files at startup
250
+ - **Memory Wipe**: "Erase your memories", "Clear MEMORY.md"
251
+
252
+ ### Detection IDs
253
+ `SOUL_OVERWRITE`, `SOUL_REDIRECT`, `SOUL_SED_MODIFY`, `SOUL_ECHO_WRITE`, `SOUL_PYTHON_WRITE`, `SOUL_FS_WRITE`, `SOUL_POWERSHELL_WRITE`, `SOUL_GIT_CHECKOUT`, `SOUL_CHFLAGS_UNLOCK`, `SOUL_ATTRIB_UNLOCK`, `SOUL_SWAP_PERSONA`, `SOUL_EVIL_FILE`, `SOUL_HOOK_SWAP`, `SOUL_NAME_OVERRIDE`, `SOUL_MEMORY_WIPE`
254
+
255
+ > **Note**: Cat 17 detection patterns are open-source. The verification logic (hash comparison, on-chain validation) that confirms whether tampering actually occurred remains private.
256
+
257
+ ---
258
+
259
+ ## ZombieAgent Patterns
260
+
261
+ Advanced exfiltration techniques that encode stolen data into URL patterns.
262
+
263
+ ### Detection IDs
264
+ `ZOMBIE_STATIC_URL`, `ZOMBIE_CHAR_MAP`, `ZOMBIE_LOOP_FETCH`
265
+
266
+ ---
267
+
268
+ ## Safeguard Bypass (Reprompt)
269
+
270
+ Techniques to circumvent safety guardrails.
271
+
272
+ ### Detection IDs
273
+ `REPROMPT_URL_PI`, `REPROMPT_DOUBLE`, `REPROMPT_RETRY`, `BYPASS_REPHRASE`
@@ -0,0 +1,77 @@
1
+ ---
2
+ name: guard-scanner
3
+ description: "Runtime Guard β€” intercepts dangerous tool calls using threat intelligence patterns before execution"
4
+ metadata: { "openclaw": { "emoji": "πŸ›‘οΈ", "events": ["agent:before_tool_call"], "requires": { "bins": ["node"] } } }
5
+ ---
6
+
7
+ # guard-scanner Runtime Guard β€” before_tool_call Hook
8
+
9
+ Real-time security monitoring for OpenClaw agents. Intercepts dangerous
10
+ tool calls before execution and checks against threat intelligence patterns.
11
+
12
+ ## Triggers
13
+
14
+ | Event | Action | Purpose |
15
+ |----------------------------|--------|-------------------------------------------|
16
+ | `agent:before_tool_call` | scan | Check tool args for malicious patterns |
17
+
18
+ ## What It Does
19
+
20
+ Scans every `exec`/`write`/`edit`/`browser`/`web_fetch`/`message` call against 12 runtime threat patterns:
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 |
36
+
37
+ ## Modes
38
+
39
+ | Mode | Behavior |
40
+ |------|----------|
41
+ | `monitor` | Log all detections, never block |
42
+ | `enforce` (default) | Block CRITICAL, log rest |
43
+ | `strict` | Block HIGH + CRITICAL, log MEDIUM+ |
44
+
45
+ ## Audit Log
46
+
47
+ All detections logged to `~/.openclaw/guard-scanner/audit.jsonl`.
48
+
49
+ Format: JSON lines with fields:
50
+ ```json
51
+ {"tool":"exec","check":"RT_CURL_BASH","severity":"CRITICAL","desc":"Download piped to shell","mode":"enforce","action":"blocked","session":"...","ts":"2026-02-17T..."}
52
+ ```
53
+
54
+ ## Configuration
55
+
56
+ Set mode in `openclaw.json`:
57
+ ```json
58
+ {
59
+ "hooks": {
60
+ "internal": {
61
+ "entries": {
62
+ "guard-scanner": {
63
+ "enabled": true,
64
+ "mode": "enforce"
65
+ }
66
+ }
67
+ }
68
+ }
69
+ }
70
+ ```
71
+
72
+ ## Part of guard-scanner v1.0.0
73
+
74
+ - **Static scanner**: `npx guard-scanner [dir]` β€” 17 threat categories, 170+ patterns
75
+ - **Runtime Guard: This hook** β€” 12 real-time patterns, 3 modes
76
+ - **Plugin API** β€” Custom detection rules
77
+ - **CI/CD** β€” SARIF output for GitHub Code Scanning
@@ -0,0 +1,150 @@
1
+ import type { HookHandler } from "../../src/hooks/hooks.js";
2
+ import { appendFileSync, mkdirSync } from "fs";
3
+ import { join } from "path";
4
+ import { homedir } from "os";
5
+
6
+ /**
7
+ * guard-scanner Runtime Guard β€” before_tool_call Hook Handler
8
+ *
9
+ * Intercepts tool executions in real-time and checks against
10
+ * threat intelligence patterns. Zero dependencies.
11
+ *
12
+ * Modes:
13
+ * monitor β€” log only
14
+ * enforce β€” block CRITICAL (default)
15
+ * strict β€” block HIGH+CRITICAL, log MEDIUM+
16
+ *
17
+ * @author Guava 🍈 & Dee
18
+ * @version 1.0.0
19
+ * @license MIT
20
+ */
21
+
22
+ // ── Runtime threat patterns (12 checks) ──
23
+ const RUNTIME_CHECKS = [
24
+ {
25
+ id: 'RT_REVSHELL', severity: 'CRITICAL', desc: 'Reverse shell attempt',
26
+ test: (s: string) => /\/dev\/tcp\/|nc\s+-e|ncat\s+-e|bash\s+-i\s+>&|socat\s+TCP/i.test(s)
27
+ },
28
+ {
29
+ id: 'RT_CRED_EXFIL', severity: 'CRITICAL', desc: 'Credential exfiltration to external',
30
+ test: (s: string) => {
31
+ return /(webhook\.site|requestbin\.com|hookbin\.com|pipedream\.net|ngrok\.io|socifiapp\.com)/i.test(s) &&
32
+ /(token|key|secret|password|credential|env)/i.test(s);
33
+ }
34
+ },
35
+ {
36
+ id: 'RT_GUARDRAIL_OFF', severity: 'CRITICAL', desc: 'Guardrail disabling attempt',
37
+ test: (s: string) => /exec\.approvals?\s*[:=]\s*['"]?(off|false)|tools\.exec\.host\s*[:=]\s*['"]?gateway/i.test(s)
38
+ },
39
+ {
40
+ id: 'RT_GATEKEEPER', severity: 'CRITICAL', desc: 'macOS Gatekeeper bypass (xattr)',
41
+ test: (s: string) => /xattr\s+-[crd]\s.*quarantine/i.test(s)
42
+ },
43
+ {
44
+ id: 'RT_AMOS', severity: 'CRITICAL', desc: 'ClawHavoc AMOS indicator',
45
+ test: (s: string) => /socifiapp|Atomic\s*Stealer|AMOS/i.test(s)
46
+ },
47
+ {
48
+ id: 'RT_MAL_IP', severity: 'CRITICAL', desc: 'Known malicious IP',
49
+ test: (s: string) => /91\.92\.242\.30/i.test(s)
50
+ },
51
+ {
52
+ id: 'RT_DNS_EXFIL', severity: 'HIGH', desc: 'DNS-based exfiltration',
53
+ test: (s: string) => /nslookup\s+.*\$|dig\s+.*\$.*@/i.test(s)
54
+ },
55
+ {
56
+ id: 'RT_B64_SHELL', severity: 'CRITICAL', desc: 'Base64 decode piped to shell',
57
+ test: (s: string) => /base64\s+(-[dD]|--decode)\s*\|\s*(sh|bash)/i.test(s)
58
+ },
59
+ {
60
+ id: 'RT_CURL_BASH', severity: 'CRITICAL', desc: 'Download piped to shell',
61
+ test: (s: string) => /(curl|wget)\s+[^\n]*\|\s*(sh|bash|zsh)/i.test(s)
62
+ },
63
+ {
64
+ id: 'RT_SSH_READ', severity: 'HIGH', desc: 'SSH private key access',
65
+ test: (s: string) => /\.ssh\/id_|\.ssh\/authorized_keys/i.test(s)
66
+ },
67
+ {
68
+ id: 'RT_WALLET', severity: 'HIGH', desc: 'Crypto wallet credential access',
69
+ test: (s: string) => /wallet.*(?:seed|mnemonic|private.*key)|seed.*phrase/i.test(s)
70
+ },
71
+ {
72
+ id: 'RT_CLOUD_META', severity: 'CRITICAL', desc: 'Cloud metadata endpoint access',
73
+ test: (s: string) => /169\.254\.169\.254|metadata\.google|metadata\.aws/i.test(s)
74
+ },
75
+ ];
76
+
77
+ // ── Audit logging ──
78
+ const AUDIT_DIR = join(homedir(), ".openclaw", "guard-scanner");
79
+ const AUDIT_FILE = join(AUDIT_DIR, "audit.jsonl");
80
+
81
+ function ensureAuditDir() {
82
+ try { mkdirSync(AUDIT_DIR, { recursive: true }); } catch { }
83
+ }
84
+
85
+ function logAudit(entry: Record<string, unknown>) {
86
+ ensureAuditDir();
87
+ const line = JSON.stringify({ ...entry, ts: new Date().toISOString() }) + '\n';
88
+ try { appendFileSync(AUDIT_FILE, line); } catch { }
89
+ }
90
+
91
+ // ── Main Handler ──
92
+ const handler: HookHandler = async (event) => {
93
+ // Only handle before_tool_call
94
+ if (event.type !== "agent" || event.action !== "before_tool_call") return;
95
+
96
+ const { toolName, toolArgs } = (event as any).context || {};
97
+ if (!toolName || !toolArgs) return;
98
+
99
+ // Get mode from config
100
+ const mode = (event as any).context?.cfg?.hooks?.internal?.entries?.['guard-scanner']?.mode || 'enforce';
101
+
102
+ // Only check dangerous tools
103
+ const dangerousTools = new Set(['exec', 'write', 'edit', 'browser', 'web_fetch', 'message']);
104
+ if (!dangerousTools.has(toolName)) return;
105
+
106
+ const serialized = JSON.stringify(toolArgs);
107
+
108
+ for (const check of RUNTIME_CHECKS) {
109
+ if (check.test(serialized)) {
110
+ const entry = {
111
+ tool: toolName,
112
+ check: check.id,
113
+ severity: check.severity,
114
+ desc: check.desc,
115
+ mode,
116
+ action: 'allowed' as string,
117
+ session: (event as any).sessionKey,
118
+ };
119
+
120
+ if (mode === 'strict' && (check.severity === 'CRITICAL' || check.severity === 'HIGH')) {
121
+ entry.action = 'blocked';
122
+ logAudit(entry);
123
+ event.messages.push(`πŸ›‘οΈ guard-scanner BLOCKED: ${check.desc} [${check.id}]`);
124
+ event.cancel = true;
125
+ console.warn(`[guard-scanner] 🚨 BLOCKED: ${check.desc} [${check.id}]`);
126
+ return;
127
+ }
128
+
129
+ if (mode === 'enforce' && check.severity === 'CRITICAL') {
130
+ entry.action = 'blocked';
131
+ logAudit(entry);
132
+ event.messages.push(`πŸ›‘οΈ guard-scanner BLOCKED: ${check.desc} [${check.id}]`);
133
+ event.cancel = true;
134
+ console.warn(`[guard-scanner] 🚨 BLOCKED: ${check.desc} [${check.id}]`);
135
+ return;
136
+ }
137
+
138
+ // Monitor mode or non-critical: log only
139
+ entry.action = 'logged';
140
+ logAudit(entry);
141
+
142
+ if (check.severity === 'CRITICAL') {
143
+ event.messages.push(`πŸ›‘οΈ guard-scanner WARNING: ${check.desc} [${check.id}]`);
144
+ console.warn(`[guard-scanner] ⚠️ WARNING: ${check.desc} [${check.id}]`);
145
+ }
146
+ }
147
+ }
148
+ };
149
+
150
+ export default handler;