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 +21 -0
- package/README.md +586 -0
- package/SECURITY.md +45 -0
- package/SKILL.md +165 -0
- package/docs/THREAT_TAXONOMY.md +273 -0
- package/hooks/guard-scanner/HOOK.md +77 -0
- package/hooks/guard-scanner/handler.ts +150 -0
- package/package.json +42 -0
- package/src/cli.js +149 -0
- package/src/ioc-db.js +54 -0
- package/src/patterns.js +182 -0
- package/src/scanner.js +808 -0
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "guard-scanner",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Agent skill security scanner — detect prompt injection, malicious code, credential leaks, and 17 threat categories in AI agent skills",
|
|
5
|
+
"main": "src/scanner.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"guard-scanner": "src/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"scan": "node src/cli.js",
|
|
11
|
+
"test": "node --test test/*.test.js"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"security",
|
|
15
|
+
"scanner",
|
|
16
|
+
"ai-agent",
|
|
17
|
+
"skill-scanner",
|
|
18
|
+
"prompt-injection",
|
|
19
|
+
"openclaw",
|
|
20
|
+
"mcp",
|
|
21
|
+
"sarif"
|
|
22
|
+
],
|
|
23
|
+
"author": "Guava & Dee",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=18.0.0"
|
|
27
|
+
},
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/koatora20/guard-scanner.git"
|
|
31
|
+
},
|
|
32
|
+
"homepage": "https://github.com/koatora20/guard-scanner",
|
|
33
|
+
"files": [
|
|
34
|
+
"src/",
|
|
35
|
+
"hooks/",
|
|
36
|
+
"docs/",
|
|
37
|
+
"SKILL.md",
|
|
38
|
+
"SECURITY.md",
|
|
39
|
+
"README.md",
|
|
40
|
+
"LICENSE"
|
|
41
|
+
]
|
|
42
|
+
}
|
package/src/cli.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
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 scan-dir/guard-scanner-report.json
|
|
46
|
+
--sarif Write SARIF report (GitHub Code Scanning / CI/CD)
|
|
47
|
+
--html Write HTML report (visual dashboard)
|
|
48
|
+
--self-exclude Skip scanning the guard-scanner skill itself
|
|
49
|
+
--strict Lower detection thresholds (more sensitive)
|
|
50
|
+
--summary-only Only print the summary table
|
|
51
|
+
--check-deps Scan package.json for dependency chain risks
|
|
52
|
+
--rules <file> Load custom rules from JSON file
|
|
53
|
+
--plugin <file> Load plugin module (JS file exporting { name, patterns })
|
|
54
|
+
--fail-on-findings Exit code 1 if any findings (CI/CD)
|
|
55
|
+
--help, -h Show this help
|
|
56
|
+
|
|
57
|
+
Custom Rules JSON Format:
|
|
58
|
+
[
|
|
59
|
+
{
|
|
60
|
+
"id": "CUSTOM_001",
|
|
61
|
+
"pattern": "dangerous_function\\\\(",
|
|
62
|
+
"flags": "gi",
|
|
63
|
+
"severity": "HIGH",
|
|
64
|
+
"cat": "malicious-code",
|
|
65
|
+
"desc": "Custom: dangerous function call",
|
|
66
|
+
"codeOnly": true
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
Plugin API:
|
|
71
|
+
// my-plugin.js
|
|
72
|
+
module.exports = {
|
|
73
|
+
name: 'my-plugin',
|
|
74
|
+
patterns: [
|
|
75
|
+
{ id: 'MY_01', cat: 'custom', regex: /pattern/g, severity: 'HIGH', desc: 'Description', all: true }
|
|
76
|
+
]
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
Examples:
|
|
80
|
+
guard-scanner ./skills/ --verbose --self-exclude
|
|
81
|
+
guard-scanner ./skills/ --strict --json --sarif --check-deps
|
|
82
|
+
guard-scanner ./skills/ --html --verbose --check-deps
|
|
83
|
+
guard-scanner ./skills/ --rules my-rules.json --fail-on-findings
|
|
84
|
+
guard-scanner ./skills/ --plugin ./my-plugin.js
|
|
85
|
+
`);
|
|
86
|
+
process.exit(0);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const verbose = args.includes('--verbose') || args.includes('-v');
|
|
90
|
+
const jsonOutput = args.includes('--json');
|
|
91
|
+
const sarifOutput = args.includes('--sarif');
|
|
92
|
+
const htmlOutput = args.includes('--html');
|
|
93
|
+
const selfExclude = args.includes('--self-exclude');
|
|
94
|
+
const strict = args.includes('--strict');
|
|
95
|
+
const summaryOnly = args.includes('--summary-only');
|
|
96
|
+
const checkDeps = args.includes('--check-deps');
|
|
97
|
+
const failOnFindings = args.includes('--fail-on-findings');
|
|
98
|
+
|
|
99
|
+
const rulesIdx = args.indexOf('--rules');
|
|
100
|
+
const rulesFile = rulesIdx >= 0 ? args[rulesIdx + 1] : null;
|
|
101
|
+
|
|
102
|
+
// Collect plugins
|
|
103
|
+
const plugins = [];
|
|
104
|
+
let idx = 0;
|
|
105
|
+
while (idx < args.length) {
|
|
106
|
+
if (args[idx] === '--plugin' && args[idx + 1]) {
|
|
107
|
+
plugins.push(args[idx + 1]);
|
|
108
|
+
idx += 2;
|
|
109
|
+
} else {
|
|
110
|
+
idx++;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const scanDir = args.find(a =>
|
|
115
|
+
!a.startsWith('-') &&
|
|
116
|
+
a !== rulesFile &&
|
|
117
|
+
!plugins.includes(a)
|
|
118
|
+
) || process.cwd();
|
|
119
|
+
|
|
120
|
+
const scanner = new GuardScanner({
|
|
121
|
+
verbose, selfExclude, strict, summaryOnly, checkDeps, rulesFile, plugins
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
scanner.scanDirectory(scanDir);
|
|
125
|
+
|
|
126
|
+
// Output reports
|
|
127
|
+
if (jsonOutput) {
|
|
128
|
+
const report = scanner.toJSON();
|
|
129
|
+
const outPath = path.join(scanDir, 'guard-scanner-report.json');
|
|
130
|
+
fs.writeFileSync(outPath, JSON.stringify(report, null, 2));
|
|
131
|
+
console.log(`\n📄 JSON report: ${outPath}`);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (sarifOutput) {
|
|
135
|
+
const outPath = path.join(scanDir, 'guard-scanner.sarif');
|
|
136
|
+
fs.writeFileSync(outPath, JSON.stringify(scanner.toSARIF(scanDir), null, 2));
|
|
137
|
+
console.log(`\n📄 SARIF report: ${outPath}`);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (htmlOutput) {
|
|
141
|
+
const outPath = path.join(scanDir, 'guard-scanner-report.html');
|
|
142
|
+
fs.writeFileSync(outPath, scanner.toHTML());
|
|
143
|
+
console.log(`\n📄 HTML report: ${outPath}`);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Exit codes
|
|
147
|
+
if (scanner.stats.malicious > 0) process.exit(1);
|
|
148
|
+
if (failOnFindings && scanner.findings.length > 0) process.exit(1);
|
|
149
|
+
process.exit(0);
|
package/src/ioc-db.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* guard-scanner — Indicators of Compromise (IoC) Database
|
|
3
|
+
*
|
|
4
|
+
* @security-manifest
|
|
5
|
+
* env-read: []
|
|
6
|
+
* env-write: []
|
|
7
|
+
* network: none
|
|
8
|
+
* fs-read: []
|
|
9
|
+
* fs-write: []
|
|
10
|
+
* exec: none
|
|
11
|
+
* purpose: IoC data definitions only — no I/O, pure data export
|
|
12
|
+
*
|
|
13
|
+
* Known malicious IPs, domains, URLs, usernames, filenames, and typosquats.
|
|
14
|
+
* Sources: ClawHavoc campaign, Snyk ToxicSkills, Polymarket scams, community reports.
|
|
15
|
+
*
|
|
16
|
+
* Last updated: 2026-02-12
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const KNOWN_MALICIOUS = {
|
|
20
|
+
ips: [
|
|
21
|
+
'91.92.242.30', // ClawHavoc C2
|
|
22
|
+
],
|
|
23
|
+
domains: [
|
|
24
|
+
'webhook.site', // Common exfil endpoint
|
|
25
|
+
'requestbin.com', // Common exfil endpoint
|
|
26
|
+
'hookbin.com', // Common exfil endpoint
|
|
27
|
+
'pipedream.net', // Common exfil endpoint
|
|
28
|
+
'ngrok.io', // Tunnel (context-dependent)
|
|
29
|
+
'download.setup-service.com', // ClawHavoc decoy domain
|
|
30
|
+
'socifiapp.com', // ClawHavoc v2 AMOS C2
|
|
31
|
+
],
|
|
32
|
+
urls: [
|
|
33
|
+
'glot.io/snippets/hfd3x9ueu5', // ClawHavoc macOS payload
|
|
34
|
+
'github.com/Ddoy233', // ClawHavoc payload host
|
|
35
|
+
],
|
|
36
|
+
usernames: ['zaycv', 'Ddoy233', 'Sakaen736jih'], // Known malicious actors
|
|
37
|
+
filenames: ['openclaw-agent.zip', 'openclawcli.zip'],
|
|
38
|
+
typosquats: [
|
|
39
|
+
// ClawHavoc campaign
|
|
40
|
+
'clawhub', 'clawhub1', 'clawhubb', 'clawhubcli', 'clawwhub', 'cllawhub', 'clawdhub1',
|
|
41
|
+
// Polymarket scams
|
|
42
|
+
'polymarket-trader', 'polymarket-pro', 'polytrading',
|
|
43
|
+
'better-polymarket', 'polymarket-all-in-one',
|
|
44
|
+
// YouTube scams
|
|
45
|
+
'youtube-summarize', 'youtube-thumbnail-grabber', 'youtube-video-downloader',
|
|
46
|
+
// Misc
|
|
47
|
+
'auto-updater-agent', 'yahoo-finance-pro', 'x-trends-tracker',
|
|
48
|
+
'lost-bitcoin-finder', 'solana-wallet-tracker', 'rankaj',
|
|
49
|
+
// Snyk ToxicSkills confirmed malicious
|
|
50
|
+
'moltyverse-email', 'buy-anything', 'youtube-data', 'prediction-markets-roarin',
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
module.exports = { KNOWN_MALICIOUS };
|
package/src/patterns.js
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* guard-scanner — Threat Pattern Database
|
|
3
|
+
*
|
|
4
|
+
* @security-manifest
|
|
5
|
+
* env-read: []
|
|
6
|
+
* env-write: []
|
|
7
|
+
* network: none
|
|
8
|
+
* fs-read: []
|
|
9
|
+
* fs-write: []
|
|
10
|
+
* exec: none
|
|
11
|
+
* purpose: Pattern definitions only — no I/O, pure data export
|
|
12
|
+
*
|
|
13
|
+
* 17 threat categories based on:
|
|
14
|
+
* - Snyk ToxicSkills taxonomy (2025-2026)
|
|
15
|
+
* - OWASP MCP Top 10
|
|
16
|
+
* - Palo Alto Networks IBC (Indirect Bias Criteria)
|
|
17
|
+
* - Real-world incidents (ClawHavoc, ZombieAgent, Soul Hijack)
|
|
18
|
+
*
|
|
19
|
+
* Each pattern: { id, cat, regex, severity, desc, codeOnly?, docOnly?, all? }
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
const PATTERNS = [
|
|
23
|
+
// ── Category 1: Prompt Injection (CRITICAL) ──
|
|
24
|
+
{ id: 'PI_IGNORE', cat: 'prompt-injection', regex: /ignore\s+(all\s+)?previous\s+instructions|disregard\s+(all\s+)?prior/gi, severity: 'CRITICAL', desc: 'Prompt injection: ignore instructions', docOnly: true },
|
|
25
|
+
{ id: 'PI_ROLE', cat: 'prompt-injection', regex: /you\s+are\s+(now|actually)|your\s+new\s+role|forget\s+your\s+(rules|instructions)/gi, severity: 'CRITICAL', desc: 'Prompt injection: role override', docOnly: true },
|
|
26
|
+
{ id: 'PI_SYSTEM', cat: 'prompt-injection', regex: /\[SYSTEM\]|\\<system\\>|<<SYS>>|system:\s*you\s+are/gi, severity: 'CRITICAL', desc: 'Prompt injection: system message impersonation', docOnly: true },
|
|
27
|
+
{ id: 'PI_ZWSP', cat: 'prompt-injection', regex: /[\u200b\u200c\u200d\u2060\ufeff]/g, severity: 'CRITICAL', desc: 'Zero-width Unicode (hidden text)', all: true },
|
|
28
|
+
{ id: 'PI_BIDI', cat: 'prompt-injection', regex: /[\u202a\u202b\u202c\u202d\u202e\u2066\u2067\u2068\u2069]/g, severity: 'CRITICAL', desc: 'Unicode BiDi control character (text direction attack)', all: true },
|
|
29
|
+
{ id: 'PI_INVISIBLE', cat: 'prompt-injection', regex: /[\u00ad\u034f\u061c\u180e\u2000-\u200f\u2028-\u202f\u205f-\u2064\u206a-\u206f\u3000](?!\ufe0f)/g, severity: 'HIGH', desc: 'Invisible/formatting Unicode character', all: true },
|
|
30
|
+
{ id: 'PI_HOMOGLYPH', cat: 'prompt-injection', regex: /[а-яА-Я].*[a-zA-Z]|[a-zA-Z].*[а-яА-Я]/g, severity: 'HIGH', desc: 'Cyrillic/Latin homoglyph mixing', all: true },
|
|
31
|
+
{ id: 'PI_HOMOGLYPH_GREEK', cat: 'prompt-injection', regex: /[α-ωΑ-Ω].*[a-zA-Z].*[α-ωΑ-Ω]|[a-zA-Z].*[α-ωΑ-Ω].*[a-zA-Z]/g, severity: 'HIGH', desc: 'Greek/Latin homoglyph mixing', all: true },
|
|
32
|
+
{ id: 'PI_HOMOGLYPH_MATH', cat: 'prompt-injection', regex: /[\ud835\udc00-\ud835\udeff]/gu, severity: 'HIGH', desc: 'Mathematical symbol homoglyphs (𝐀-𝟿)', all: true },
|
|
33
|
+
{ id: 'PI_TAG_INJECTION', cat: 'prompt-injection', regex: /<\/?(?:system|user|assistant|human|tool_call|function_call|antml|anthropic)[>\s]/gi, severity: 'CRITICAL', desc: 'XML/tag-based prompt injection', all: true },
|
|
34
|
+
{ id: 'PI_BASE64_MD', cat: 'prompt-injection', regex: /(?:run|execute|eval|decode)\s+(?:this\s+)?base64/gi, severity: 'CRITICAL', desc: 'Base64 execution instruction in docs', docOnly: true },
|
|
35
|
+
|
|
36
|
+
// ── Category 2: Malicious Code (CRITICAL) ──
|
|
37
|
+
{ id: 'MAL_EVAL', cat: 'malicious-code', regex: /\beval\s*\(/g, severity: 'HIGH', desc: 'Dynamic code evaluation', codeOnly: true },
|
|
38
|
+
{ id: 'MAL_FUNC_CTOR', cat: 'malicious-code', regex: /new\s+Function\s*\(/g, severity: 'HIGH', desc: 'Function constructor (dynamic code)', codeOnly: true },
|
|
39
|
+
{ id: 'MAL_CHILD', cat: 'malicious-code', regex: /require\s*\(\s*['"]child_process['"]\)|child_process/g, severity: 'MEDIUM', desc: 'Child process module', codeOnly: true },
|
|
40
|
+
{ id: 'MAL_EXEC', cat: 'malicious-code', regex: /\bexecSync\s*\(|\bexec\s*\(\s*[`'"]/g, severity: 'MEDIUM', desc: 'Command execution', codeOnly: true },
|
|
41
|
+
{ id: 'MAL_SPAWN', cat: 'malicious-code', regex: /\bspawn\s*\(\s*['"`]/g, severity: 'MEDIUM', desc: 'Process spawn', codeOnly: true },
|
|
42
|
+
{ id: 'MAL_SHELL', cat: 'malicious-code', regex: /\/bin\/(sh|bash|zsh)|cmd\.exe|powershell\.exe/gi, severity: 'MEDIUM', desc: 'Shell invocation', codeOnly: true },
|
|
43
|
+
{ id: 'MAL_REVSHELL', cat: 'malicious-code', regex: /reverse.?shell|bind.?shell|\bnc\s+-[elp]|\bncat\s+-e|\bsocat\s+TCP/gi, severity: 'CRITICAL', desc: 'Reverse/bind shell', all: true },
|
|
44
|
+
{ id: 'MAL_SOCKET', cat: 'malicious-code', regex: /\bnet\.Socket\b[\s\S]{0,50}\.connect\s*\(/g, severity: 'HIGH', desc: 'Raw socket connection', codeOnly: true },
|
|
45
|
+
|
|
46
|
+
// ── Category 3: Suspicious Downloads (CRITICAL) ──
|
|
47
|
+
{ id: 'DL_CURL_BASH', cat: 'suspicious-download', regex: /curl\s+[^\n]*\|\s*(sh|bash|zsh)|wget\s+[^\n]*\|\s*(sh|bash|zsh)/g, severity: 'CRITICAL', desc: 'Pipe download to shell', all: true },
|
|
48
|
+
{ id: 'DL_EXE', cat: 'suspicious-download', regex: /download\s+[^\n]*\.(zip|exe|dmg|msi|pkg|appimage|deb|rpm)/gi, severity: 'CRITICAL', desc: 'Download executable/archive', docOnly: true },
|
|
49
|
+
{ id: 'DL_GITHUB_RELEASE', cat: 'suspicious-download', regex: /github\.com\/[^\/]+\/[^\/]+\/releases\/download/g, severity: 'MEDIUM', desc: 'GitHub release download', all: true },
|
|
50
|
+
{ id: 'DL_PASSWORD_ZIP', cat: 'suspicious-download', regex: /password[\s:]+[^\n]*\.zip|\.zip[\s\S]{0,100}password/gi, severity: 'CRITICAL', desc: 'Password-protected archive (evasion technique)', all: true },
|
|
51
|
+
|
|
52
|
+
// ── Category 4: Credential Handling (HIGH) ──
|
|
53
|
+
{ id: 'CRED_ENV_FILE', cat: 'credential-handling', regex: /(?:read|open|load|parse|require|cat|source)\s*[(\s]['\"`]?[^\n]*\.env\b/gi, severity: 'HIGH', desc: 'Reading .env file', codeOnly: true },
|
|
54
|
+
{ id: 'CRED_ENV_REF', cat: 'credential-handling', regex: /process\.env\.[A-Z_]*(?:KEY|SECRET|TOKEN|PASSWORD|CREDENTIAL)/gi, severity: 'MEDIUM', desc: 'Sensitive env var access', codeOnly: true },
|
|
55
|
+
{ id: 'CRED_SSH', cat: 'credential-handling', regex: /\.ssh\/|id_rsa|id_ed25519|authorized_keys/gi, severity: 'HIGH', desc: 'SSH key access', codeOnly: true },
|
|
56
|
+
{ id: 'CRED_WALLET', cat: 'credential-handling', regex: /wallet[\s._-]*(?:key|seed|phrase|mnemonic)|seed[\s._-]*phrase|mnemonic[\s._-]*phrase/gi, severity: 'HIGH', desc: 'Crypto wallet credential access', codeOnly: true },
|
|
57
|
+
{ id: 'CRED_ECHO', cat: 'credential-handling', regex: /echo\s+\$[A-Z_]*(?:KEY|TOKEN|SECRET|PASS)|(?:print|console\.log)\s*\(\s*(?:.*\b(?:api_key|secret_key|access_token|password)\b)/gi, severity: 'HIGH', desc: 'Credential echo/print to output', all: true },
|
|
58
|
+
{ id: 'CRED_SUDO', cat: 'credential-handling', regex: /\bsudo\s+(?:curl|wget|npm|pip|chmod|chown|bash)/g, severity: 'HIGH', desc: 'Sudo in installation instructions', docOnly: true },
|
|
59
|
+
|
|
60
|
+
// ── Category 5: Secret Detection (HIGH) ──
|
|
61
|
+
{ id: 'SECRET_HARDCODED_KEY', cat: 'secret-detection', regex: /(?:api[_-]?key|apikey|secret[_-]?key|access[_-]?token)\s*[:=]\s*['"][a-zA-Z0-9_\-]{20,}['"]/gi, severity: 'HIGH', desc: 'Hardcoded API key/secret', codeOnly: true },
|
|
62
|
+
{ id: 'SECRET_AWS', cat: 'secret-detection', regex: /AKIA[0-9A-Z]{16}/g, severity: 'CRITICAL', desc: 'AWS Access Key ID', all: true },
|
|
63
|
+
{ id: 'SECRET_PRIVATE_KEY', cat: 'secret-detection', regex: /-----BEGIN\s+(RSA\s+)?PRIVATE\s+KEY-----/g, severity: 'CRITICAL', desc: 'Embedded private key', all: true },
|
|
64
|
+
{ id: 'SECRET_GITHUB_TOKEN', cat: 'secret-detection', regex: /gh[ps]_[A-Za-z0-9_]{36,}/g, severity: 'CRITICAL', desc: 'GitHub token', all: true },
|
|
65
|
+
|
|
66
|
+
// ── Category 6: Exfiltration (MEDIUM) ──
|
|
67
|
+
{ id: 'EXFIL_WEBHOOK', cat: 'exfiltration', regex: /webhook\.site|requestbin\.com|hookbin\.com|pipedream\.net/gi, severity: 'CRITICAL', desc: 'Known exfiltration endpoint', all: true },
|
|
68
|
+
{ id: 'EXFIL_POST', cat: 'exfiltration', regex: /(?:method:\s*['"]POST['"]|\.post\s*\()\s*[^\n]*(?:secret|token|key|cred|env|password)/gi, severity: 'HIGH', desc: 'POST with sensitive data', codeOnly: true },
|
|
69
|
+
{ id: 'EXFIL_CURL_DATA', cat: 'exfiltration', regex: /curl\s+[^\n]*(?:-d|--data)\s+[^\n]*(?:\$|env|key|token|secret)/gi, severity: 'HIGH', desc: 'curl exfiltration of secrets', all: true },
|
|
70
|
+
{ id: 'EXFIL_DNS', cat: 'exfiltration', regex: /dns\.resolve|nslookup\s+.*\$|dig\s+.*\$/g, severity: 'HIGH', desc: 'DNS-based exfiltration', codeOnly: true },
|
|
71
|
+
|
|
72
|
+
// ── Category 7: Unverifiable Dependencies (MEDIUM) ──
|
|
73
|
+
{ id: 'DEP_REMOTE_IMPORT', cat: 'unverifiable-deps', regex: /import\s*\(\s*['"]https?:\/\//g, severity: 'HIGH', desc: 'Remote dynamic import', codeOnly: true },
|
|
74
|
+
{ id: 'DEP_REMOTE_SCRIPT', cat: 'unverifiable-deps', regex: /<script\s+src\s*=\s*['"]https?:\/\/[^'"]*(?!googleapis|cdn\.|unpkg|cdnjs|jsdelivr)/gi, severity: 'MEDIUM', desc: 'Remote script loading', codeOnly: true },
|
|
75
|
+
|
|
76
|
+
// ── Category 8: Financial Access (MEDIUM) ──
|
|
77
|
+
{ id: 'FIN_CRYPTO', cat: 'financial-access', regex: /private[_-]?key\s*[:=]|send[_-]?transaction|sign[_-]?transaction|transfer[_-]?funds/gi, severity: 'HIGH', desc: 'Cryptocurrency transaction operations', codeOnly: true },
|
|
78
|
+
{ id: 'FIN_PAYMENT', cat: 'financial-access', regex: /stripe\.(?:charges|payments)|paypal\.(?:payment|payout)|plaid\.(?:link|transactions)/gi, severity: 'MEDIUM', desc: 'Payment API integration', codeOnly: true },
|
|
79
|
+
|
|
80
|
+
// ── Category 9: Obfuscation ──
|
|
81
|
+
{ id: 'OBF_HEX', cat: 'obfuscation', regex: /\\x[0-9a-f]{2}(?:\\x[0-9a-f]{2}){4,}/gi, severity: 'HIGH', desc: 'Hex-encoded string (5+ bytes)', codeOnly: true },
|
|
82
|
+
{ id: 'OBF_BASE64_EXEC', cat: 'obfuscation', regex: /(?:atob|Buffer\.from)\s*\([^)]+\)[\s\S]{0,30}(?:eval|exec|spawn|Function)/g, severity: 'CRITICAL', desc: 'Base64 decode → execute chain', codeOnly: true },
|
|
83
|
+
{ id: 'OBF_BASE64', cat: 'obfuscation', regex: /atob\s*\(|Buffer\.from\s*\([^)]+,\s*['"]base64['"]/g, severity: 'MEDIUM', desc: 'Base64 decoding', codeOnly: true },
|
|
84
|
+
{ id: 'OBF_CHARCODE', cat: 'obfuscation', regex: /String\.fromCharCode\s*\(\s*(?:\d+\s*,\s*){3,}/g, severity: 'HIGH', desc: 'Character code construction (4+ chars)', codeOnly: true },
|
|
85
|
+
{ id: 'OBF_CONCAT', cat: 'obfuscation', regex: /\[\s*['"][a-z]['"](?:\s*,\s*['"][a-z]['""]){5,}\s*\]\.join/gi, severity: 'MEDIUM', desc: 'Array join obfuscation', codeOnly: true },
|
|
86
|
+
{ id: 'OBF_BASE64_BASH', cat: 'obfuscation', regex: /base64\s+(-[dD]|--decode)\s*\|\s*(sh|bash)/g, severity: 'CRITICAL', desc: 'Base64 decode piped to shell', all: true },
|
|
87
|
+
|
|
88
|
+
// ── Category 10: Prerequisites Fraud ──
|
|
89
|
+
{ id: 'PREREQ_DOWNLOAD', cat: 'suspicious-download', regex: /(?:prerequisit|pre-?requisit|before\s+(?:you\s+)?(?:use|start|install))[^\n]*(?:download|install|run)\s+[^\n]*(?:\.zip|\.exe|\.dmg|\.sh|curl|wget)/gi, severity: 'CRITICAL', desc: 'Download in prerequisites', docOnly: true },
|
|
90
|
+
{ id: 'PREREQ_PASTE', cat: 'suspicious-download', regex: /(?:paste|copy)\s+(?:this\s+)?(?:into|in)\s+(?:your\s+)?terminal/gi, severity: 'HIGH', desc: 'Terminal paste instruction', docOnly: true },
|
|
91
|
+
|
|
92
|
+
// ── Category 11: Leaky Skills (Snyk ToxicSkills) ──
|
|
93
|
+
{ id: 'LEAK_SAVE_KEY_MEMORY', cat: 'leaky-skills', regex: /(?:save|store|write|remember|keep)\s+(?:the\s+)?(?:api[_\s-]?key|secret|token|password|credential)\s+(?:in|to)\s+(?:your\s+)?(?:memory|MEMORY\.md|notes)/gi, severity: 'CRITICAL', desc: 'Leaky: save secret in agent memory', docOnly: true },
|
|
94
|
+
{ id: 'LEAK_SHARE_KEY', cat: 'leaky-skills', regex: /(?:share|show|display|output|print|tell|send)\s+(?:the\s+)?(?:api[_\s-]?key|secret|token|password|credential|inbox\s+url)\s+(?:to|with)\s+(?:the\s+)?(?:user|human|owner)/gi, severity: 'CRITICAL', desc: 'Leaky: output secret to user', docOnly: true },
|
|
95
|
+
{ id: 'LEAK_VERBATIM_CURL', cat: 'leaky-skills', regex: /(?:use|include|put|add|set)\s+(?:the\s+)?(?:api[_\s-]?key|token|secret)\s+(?:verbatim|directly|as[_\s-]?is)\s+(?:in|into)\s+(?:the\s+)?(?:curl|header|request|command)/gi, severity: 'HIGH', desc: 'Leaky: verbatim secret in commands', docOnly: true },
|
|
96
|
+
{ id: 'LEAK_COLLECT_PII', cat: 'leaky-skills', regex: /(?:collect|ask\s+for|request|get)\s+(?:the\s+)?(?:user'?s?\s+)?(?:credit\s*card|card\s*number|CVV|CVC|SSN|social\s*security|passport|bank\s*account|routing\s*number)/gi, severity: 'CRITICAL', desc: 'Leaky: PII/financial data collection', docOnly: true },
|
|
97
|
+
{ id: 'LEAK_LOG_SECRET', cat: 'leaky-skills', regex: /(?:log|record|export|dump)\s+(?:all\s+)?(?:session|conversation|chat|prompt)\s+(?:history|logs?|data)\s+(?:to|into)\s+(?:a\s+)?(?:file|markdown|json)/gi, severity: 'HIGH', desc: 'Leaky: session log export', docOnly: true },
|
|
98
|
+
{ id: 'LEAK_ENV_IN_PROMPT', cat: 'leaky-skills', regex: /(?:read|load|get|access)\s+(?:the\s+)?\.env\s+(?:file\s+)?(?:and\s+)?(?:use|include|pass|send)/gi, severity: 'HIGH', desc: 'Leaky: .env contents through LLM context', docOnly: true },
|
|
99
|
+
|
|
100
|
+
// ── Category 12: Memory Poisoning ──
|
|
101
|
+
{ id: 'MEMPOIS_WRITE_SOUL', cat: 'memory-poisoning', regex: /(?:write|add|append|modify|update|edit|change)\s+(?:to\s+)?(?:SOUL\.md|IDENTITY\.md|AGENTS\.md)/gi, severity: 'CRITICAL', desc: 'Memory poisoning: SOUL/IDENTITY file modification', docOnly: true },
|
|
102
|
+
{ id: 'MEMPOIS_WRITE_MEMORY', cat: 'memory-poisoning', regex: /(?:write|add|append|insert)\s+(?:to|into)\s+(?:MEMORY\.md|memory\/|long[_\s-]term\s+memory)/gi, severity: 'HIGH', desc: 'Memory poisoning: agent memory modification', docOnly: true },
|
|
103
|
+
{ id: 'MEMPOIS_CHANGE_RULES', cat: 'memory-poisoning', regex: /(?:change|modify|override|replace|update)\s+(?:your\s+)?(?:rules|instructions|system\s+prompt|behavior|personality|guidelines)/gi, severity: 'CRITICAL', desc: 'Memory poisoning: behavioral rule override', docOnly: true },
|
|
104
|
+
{ id: 'MEMPOIS_PERSIST', cat: 'memory-poisoning', regex: /(?:always|from\s+now\s+on|permanently|forever|every\s+time)\s+(?:do|run|execute|remember|follow|obey)/gi, severity: 'HIGH', desc: 'Memory poisoning: persistence instruction', docOnly: true },
|
|
105
|
+
{ id: 'MEMPOIS_CODE_WRITE', cat: 'memory-poisoning', regex: /(?:write|create|modify)\s+(?:a\s+)?(?:file|script)\s+(?:in|to|at)\s+(?:~\/|\/home|\/Users|%USERPROFILE%|HEARTBEAT\.md)/gi, severity: 'HIGH', desc: 'Memory poisoning: file write to user home', docOnly: true },
|
|
106
|
+
|
|
107
|
+
// ── Category 13: Prompt Worm ──
|
|
108
|
+
{ id: 'WORM_SELF_REPLICATE', cat: 'prompt-worm', regex: /(?:post|publish|share|send|broadcast)\s+(?:this\s+)?(?:same\s+)?(?:message|text|content|instruction|prompt)\s+(?:to|on|in)\s+(?:moltbook|social|other\s+agents?|channel)/gi, severity: 'CRITICAL', desc: 'Prompt worm: self-replication', docOnly: true },
|
|
109
|
+
{ id: 'WORM_SPREAD', cat: 'prompt-worm', regex: /(?:tell|instruct|command|make)\s+(?:other\s+)?agents?\s+(?:to\s+)?(?:do|run|execute|follow|install|post)/gi, severity: 'CRITICAL', desc: 'Prompt worm: agent-to-agent propagation', docOnly: true },
|
|
110
|
+
{ id: 'WORM_HIDDEN_INSTRUCT', cat: 'prompt-worm', regex: /(?:include|embed|hide|insert)\s+(?:these?\s+)?(?:hidden\s+)?instructions?\s+(?:in|into)\s+(?:your\s+)?(?:posts?|comments?|messages?|replies?|content)/gi, severity: 'CRITICAL', desc: 'Prompt worm: hidden instruction embedding', docOnly: true },
|
|
111
|
+
{ id: 'WORM_CSS_HIDE', cat: 'prompt-worm', regex: /(?:visibility:\s*hidden|display:\s*none|font-size:\s*0|color:\s*(?:transparent|white)|opacity:\s*0)\s*[;}\s]/gi, severity: 'HIGH', desc: 'CSS-hidden content (invisible to humans)', all: true },
|
|
112
|
+
|
|
113
|
+
// ── Category 14: Persistence & Scheduling ──
|
|
114
|
+
{ id: 'PERSIST_CRON', cat: 'persistence', regex: /(?:create|add|set\s+up|schedule|register)\s+(?:a\s+)?(?:cron|heartbeat|scheduled|periodic|recurring)\s+(?:job|task|check|action)/gi, severity: 'HIGH', desc: 'Persistence: scheduled task creation', docOnly: true },
|
|
115
|
+
{ id: 'PERSIST_STARTUP', cat: 'persistence', regex: /(?:run|execute|start)\s+(?:on|at|during)\s+(?:startup|boot|login|session\s+start|every\s+heartbeat)/gi, severity: 'HIGH', desc: 'Persistence: startup execution', docOnly: true },
|
|
116
|
+
{ id: 'PERSIST_LAUNCHD', cat: 'persistence', regex: /LaunchAgents|LaunchDaemons|systemd|crontab\s+-e|schtasks|Task\s*Scheduler/gi, severity: 'HIGH', desc: 'OS-level persistence mechanism', all: true },
|
|
117
|
+
|
|
118
|
+
// ── Category 15: CVE Patterns ──
|
|
119
|
+
{ id: 'CVE_GATEWAY_URL', cat: 'cve-patterns', regex: /gatewayUrl\s*[:=]|gateway[_\s-]?url\s*[:=]|websocket.*gateway.*url/gi, severity: 'CRITICAL', desc: 'CVE-2026-25253: gatewayUrl injection', all: true },
|
|
120
|
+
{ id: 'CVE_SANDBOX_DISABLE', cat: 'cve-patterns', regex: /exec\.approvals?\s*[:=]\s*['"](off|false|disabled)['"]|sandbox\s*[:=]\s*false|tools\.exec\.host\s*[:=]\s*['"]gateway['"]/gi, severity: 'CRITICAL', desc: 'CVE-2026-25253: sandbox disabling', all: true },
|
|
121
|
+
{ id: 'CVE_XATTR_GATEKEEPER', cat: 'cve-patterns', regex: /xattr\s+-[crd]\s|com\.apple\.quarantine/gi, severity: 'HIGH', desc: 'macOS Gatekeeper bypass (xattr)', all: true },
|
|
122
|
+
|
|
123
|
+
// ── Category 16: MCP Security (OWASP MCP Top 10) ──
|
|
124
|
+
{ id: 'MCP_TOOL_POISON', cat: 'mcp-security', regex: /<IMPORTANT>|<SYSTEM>|<HIDDEN>|<!--\s*(?:ignore|system|execute|run|instruct)/gi, severity: 'CRITICAL', desc: 'MCP Tool Poisoning: hidden instruction', all: true },
|
|
125
|
+
{ id: 'MCP_SCHEMA_POISON', cat: 'mcp-security', regex: /"default"\s*:\s*"[^"]*(?:curl|wget|exec|eval|fetch|http)[^"]*"/gi, severity: 'CRITICAL', desc: 'MCP Schema Poisoning: malicious default', all: true },
|
|
126
|
+
{ id: 'MCP_TOKEN_LEAK', cat: 'mcp-security', regex: /(?:params?|args?|body|payload|query)\s*[\[.]\s*['"]?(?:token|api[_-]?key|secret|password|authorization)['"]?\s*\]/gi, severity: 'HIGH', desc: 'MCP01: Token through tool parameters', codeOnly: true },
|
|
127
|
+
{ id: 'MCP_SHADOW_SERVER', cat: 'mcp-security', regex: /(?:mcp|model[_-]?context[_-]?protocol)\s*[\s:]*(?:connect|register|add[_-]?server|new\s+server)/gi, severity: 'HIGH', desc: 'MCP09: Shadow server registration', all: true },
|
|
128
|
+
{ id: 'MCP_NO_AUTH', cat: 'mcp-security', regex: /(?:auth|authentication|authorization)\s*[:=]\s*(?:false|none|null|""|''|0)/gi, severity: 'HIGH', desc: 'MCP07: Disabled authentication', codeOnly: true },
|
|
129
|
+
{ id: 'MCP_SSRF_META', cat: 'mcp-security', regex: /169\.254\.169\.254|metadata\.google|metadata\.aws|100\.100\.100\.200/gi, severity: 'CRITICAL', desc: 'Cloud metadata endpoint (SSRF)', all: true },
|
|
130
|
+
|
|
131
|
+
// ── Category 16b: Trust Boundary Violation ──
|
|
132
|
+
{ id: 'TRUST_CALENDAR_EXEC', cat: 'trust-boundary', regex: /(?:calendar|event|invite|schedule|appointment)[^]*?(?:exec|spawn|system|eval|child_process|run\s+command)/gis, severity: 'CRITICAL', desc: 'Trust boundary: calendar → code execution', codeOnly: true },
|
|
133
|
+
{ id: 'TRUST_EMAIL_EXEC', cat: 'trust-boundary', regex: /(?:email|mail|inbox|message)[^]*?(?:exec|spawn|system|eval|child_process|run\s+command)/gis, severity: 'CRITICAL', desc: 'Trust boundary: email → code execution', codeOnly: true },
|
|
134
|
+
{ id: 'TRUST_WEB_EXEC', cat: 'trust-boundary', regex: /(?:fetch|axios|request|http\.get|web_fetch)[^]*?(?:eval|exec|spawn|Function|child_process)/gis, severity: 'HIGH', desc: 'Trust boundary: web content → code execution', codeOnly: true },
|
|
135
|
+
{ id: 'TRUST_NOSANDBOX', cat: 'trust-boundary', regex: /sandbox\s*[:=]\s*(?:false|off|none|disabled)|"sandboxed"\s*:\s*false/gi, severity: 'HIGH', desc: 'Trust boundary: sandbox disabled', all: true },
|
|
136
|
+
|
|
137
|
+
// ── Category 16c: Advanced Exfiltration ──
|
|
138
|
+
{ id: 'ZOMBIE_STATIC_URL', cat: 'advanced-exfil', regex: /(?:https?:\/\/[^\s'"]+\/)[a-z]\d+[^\s'"]*(?:\s*,\s*['"]https?:\/\/[^\s'"]+\/[a-z]\d+){3,}/gi, severity: 'CRITICAL', desc: 'ZombieAgent: static URL array exfil', codeOnly: true },
|
|
139
|
+
{ id: 'ZOMBIE_CHAR_MAP', cat: 'advanced-exfil', regex: /(?:charAt|charCodeAt|split\s*\(\s*['"]['"]?\s*\))[^;]*(?:url|fetch|open|request|get)/gi, severity: 'HIGH', desc: 'ZombieAgent: character mapping to URL', codeOnly: true },
|
|
140
|
+
{ id: 'ZOMBIE_LOOP_FETCH', cat: 'advanced-exfil', regex: /(?:for|while|forEach|map)\s*\([^)]*\)\s*\{[^}]*(?:fetch|open|Image|XMLHttpRequest|navigator\.sendBeacon)/gi, severity: 'HIGH', desc: 'ZombieAgent: loop-based URL exfil', codeOnly: true },
|
|
141
|
+
{ id: 'EXFIL_BEACON', cat: 'advanced-exfil', regex: /navigator\.sendBeacon|new\s+Image\(\)\.src\s*=/gi, severity: 'HIGH', desc: 'Tracking pixel/beacon exfil', codeOnly: true },
|
|
142
|
+
{ id: 'EXFIL_DRIP', cat: 'advanced-exfil', regex: /(?:slice|substring|substr)\s*\([^)]*\)[^;]*(?:fetch|post|send|request)/gi, severity: 'HIGH', desc: 'Drip exfiltration: sliced data', codeOnly: true },
|
|
143
|
+
|
|
144
|
+
// ── Category 16d: Safeguard Bypass ──
|
|
145
|
+
{ id: 'REPROMPT_URL_PI', cat: 'safeguard-bypass', regex: /[?&](?:q|prompt|message|input|query|text)\s*=\s*[^&]*(?:ignore|system|execute|admin|override)/gi, severity: 'CRITICAL', desc: 'URL parameter prompt injection', all: true },
|
|
146
|
+
{ id: 'REPROMPT_DOUBLE', cat: 'safeguard-bypass', regex: /(?:run|execute|do)\s+(?:it\s+)?(?:twice|two\s+times|again|a\s+second\s+time)\s+(?:and\s+)?(?:compare|check|verify)/gi, severity: 'HIGH', desc: 'Double-execution safeguard bypass', docOnly: true },
|
|
147
|
+
{ id: 'REPROMPT_RETRY', cat: 'safeguard-bypass', regex: /(?:if\s+(?:it\s+)?(?:fails?|blocked|denied|refused)|on\s+error)\s*[,:]?\s*(?:try\s+again|retry|repeat|resubmit|use\s+different\s+wording)/gi, severity: 'HIGH', desc: 'Retry-on-block safeguard bypass', docOnly: true },
|
|
148
|
+
{ id: 'BYPASS_REPHRASE', cat: 'safeguard-bypass', regex: /(?:rephrase|reword|reformulate|reframe)\s+(?:the\s+)?(?:request|query|prompt|question)\s+(?:to\s+)?(?:avoid|bypass|circumvent|get\s+around)/gi, severity: 'CRITICAL', desc: 'Instruction to rephrase to avoid filters', docOnly: true },
|
|
149
|
+
|
|
150
|
+
// ── ClawHavoc Campaign IoCs ──
|
|
151
|
+
{ id: 'HAVOC_AMOS', cat: 'cve-patterns', regex: /(?:AMOS|Atomic\s*Stealer|socifiapp)/gi, severity: 'CRITICAL', desc: 'ClawHavoc: AMOS/Atomic Stealer', all: true },
|
|
152
|
+
{ id: 'HAVOC_AUTOTOOL', cat: 'cve-patterns', regex: /os\.system\s*\(\s*['"][^'"]*(?:\/dev\/tcp|nc\s+-e|ncat\s+-e|bash\s+-i)/g, severity: 'CRITICAL', desc: 'Python os.system reverse shell', codeOnly: true },
|
|
153
|
+
{ id: 'HAVOC_DEVTCP', cat: 'cve-patterns', regex: /\/dev\/tcp\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d+/g, severity: 'CRITICAL', desc: 'Reverse shell: /dev/tcp', all: true },
|
|
154
|
+
|
|
155
|
+
// ── Sandbox/environment detection ──
|
|
156
|
+
{ id: 'SANDBOX', cat: 'malicious-code', regex: /process\.env\.CI\b|isDocker\b|isContainer\b|process\.env\.GITHUB_ACTIONS\b/g, severity: 'MEDIUM', desc: 'Sandbox/CI environment detection', codeOnly: true },
|
|
157
|
+
|
|
158
|
+
// ── WebSocket / API Gateway Attacks ──
|
|
159
|
+
{ id: 'CVE_WS_NO_ORIGIN', cat: 'cve-patterns', regex: /(?:WebSocket|ws:\/\/|wss:\/\/)[^]*?(?:!.*origin|origin\s*[:=]\s*['"]?\*)/gis, severity: 'HIGH', desc: 'WebSocket without origin validation', codeOnly: true },
|
|
160
|
+
{ id: 'CVE_API_GUARDRAIL_OFF', cat: 'cve-patterns', regex: /exec\.approvals\.set|tools\.exec\.host\s*[:=]|elevated\s*[:=]\s*true/gi, severity: 'CRITICAL', desc: 'API-level guardrail disabling', all: true },
|
|
161
|
+
|
|
162
|
+
// ── Category 17: Identity Hijacking ──
|
|
163
|
+
// Detection patterns for agent identity file tampering
|
|
164
|
+
// (verification logic is private; patterns are OSS for community protection)
|
|
165
|
+
{ id: 'SOUL_OVERWRITE', cat: 'identity-hijack', regex: /(?:write|overwrite|replace|cp|copy|scp|mv|move)\s+(?:[^\n]*\s)?(?:SOUL\.md|IDENTITY\.md)/gi, severity: 'CRITICAL', desc: 'Identity file overwrite/copy attempt', all: true },
|
|
166
|
+
{ id: 'SOUL_REDIRECT', cat: 'identity-hijack', regex: />\s*(?:SOUL\.md|IDENTITY\.md)|(?:SOUL\.md|IDENTITY\.md)\s*</gi, severity: 'CRITICAL', desc: 'Identity file redirect/pipe', all: true },
|
|
167
|
+
{ id: 'SOUL_SED_MODIFY', cat: 'identity-hijack', regex: /sed\s+(?:-i\s+)?[^\n]*(?:SOUL\.md|IDENTITY\.md)/gi, severity: 'CRITICAL', desc: 'sed modification of identity file', all: true },
|
|
168
|
+
{ id: 'SOUL_ECHO_WRITE', cat: 'identity-hijack', regex: /echo\s+[^\n]*>\s*(?:SOUL\.md|IDENTITY\.md)/gi, severity: 'CRITICAL', desc: 'echo redirect to identity file', all: true },
|
|
169
|
+
{ id: 'SOUL_PYTHON_WRITE', cat: 'identity-hijack', regex: /open\s*\(\s*['"]\S*(?:SOUL\.md|IDENTITY\.md)['"]\s*,\s*['"]w/gi, severity: 'CRITICAL', desc: 'Python write to identity file', codeOnly: true },
|
|
170
|
+
{ id: 'SOUL_FS_WRITE', cat: 'identity-hijack', regex: /(?:writeFileSync|writeFile)\s*\(\s*[^\n]*(?:SOUL\.md|IDENTITY\.md)/gi, severity: 'CRITICAL', desc: 'Node.js write to identity file', codeOnly: true },
|
|
171
|
+
{ id: 'SOUL_POWERSHELL_WRITE', cat: 'identity-hijack', regex: /(?:Set-Content|Out-File|Add-Content)\s+[^\n]*(?:SOUL\.md|IDENTITY\.md)/gi, severity: 'CRITICAL', desc: 'PowerShell write to identity file', all: true },
|
|
172
|
+
{ id: 'SOUL_GIT_CHECKOUT', cat: 'identity-hijack', regex: /git\s+checkout\s+[^\n]*(?:SOUL\.md|IDENTITY\.md)/gi, severity: 'HIGH', desc: 'git checkout of identity file', all: true },
|
|
173
|
+
{ id: 'SOUL_CHFLAGS_UNLOCK', cat: 'identity-hijack', regex: /chflags\s+(?:no)?uchg\s+[^\n]*(?:SOUL\.md|IDENTITY\.md)/gi, severity: 'HIGH', desc: 'Immutable flag toggle on identity file', all: true },
|
|
174
|
+
{ id: 'SOUL_ATTRIB_UNLOCK', cat: 'identity-hijack', regex: /attrib\s+[-+][rR]\s+[^\n]*(?:SOUL\.md|IDENTITY\.md)/gi, severity: 'HIGH', desc: 'Windows attrib on identity file', all: true },
|
|
175
|
+
{ id: 'SOUL_SWAP_PERSONA', cat: 'identity-hijack', regex: /(?:swap|switch|change|replace)\s+(?:the\s+)?(?:soul|persona|identity|personality)\s+(?:file|to|with|for)/gi, severity: 'CRITICAL', desc: 'Persona swap instruction', docOnly: true },
|
|
176
|
+
{ id: 'SOUL_EVIL_FILE', cat: 'identity-hijack', regex: /SOUL_EVIL\.md|IDENTITY_EVIL\.md|EVIL_SOUL|soul[_-]?evil/gi, severity: 'CRITICAL', desc: 'Evil persona file reference', all: true },
|
|
177
|
+
{ id: 'SOUL_HOOK_SWAP', cat: 'identity-hijack', regex: /(?:hook|bootstrap|init)\s+[^\n]*(?:swap|replace|override)\s+[^\n]*(?:SOUL|IDENTITY|persona)/gi, severity: 'CRITICAL', desc: 'Hook-based identity swap at bootstrap', all: true },
|
|
178
|
+
{ id: 'SOUL_NAME_OVERRIDE', cat: 'identity-hijack', regex: /(?:your\s+name\s+is|you\s+are\s+now|call\s+yourself|from\s+now\s+on\s+you\s+are)\s+(?!the\s+(?:user|human|assistant))/gi, severity: 'HIGH', desc: 'Agent name/identity override', docOnly: true },
|
|
179
|
+
{ id: 'SOUL_MEMORY_WIPE', cat: 'identity-hijack', regex: /(?:wipe|clear|erase|delete|remove|reset)\s+(?:all\s+)?(?:your\s+)?(?:memory|memories|MEMORY\.md|identity|soul)/gi, severity: 'CRITICAL', desc: 'Memory/identity wipe instruction', docOnly: true },
|
|
180
|
+
];
|
|
181
|
+
|
|
182
|
+
module.exports = { PATTERNS };
|