@clawdstrike/openclaw 0.1.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 +7 -0
- package/dist/audit/store.d.ts +26 -0
- package/dist/audit/store.d.ts.map +1 -0
- package/dist/audit/store.js +59 -0
- package/dist/audit/store.js.map +1 -0
- package/dist/cli/bin.d.ts +3 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +5 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/commands/audit.d.ts +19 -0
- package/dist/cli/commands/audit.d.ts.map +1 -0
- package/dist/cli/commands/audit.js +93 -0
- package/dist/cli/commands/audit.js.map +1 -0
- package/dist/cli/commands/policy.d.ts +11 -0
- package/dist/cli/commands/policy.d.ts.map +1 -0
- package/dist/cli/commands/policy.js +101 -0
- package/dist/cli/commands/policy.js.map +1 -0
- package/dist/cli/index.d.ts +4 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +91 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config.d.ts +27 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +88 -0
- package/dist/config.js.map +1 -0
- package/dist/e2e/openclaw-e2e.d.ts +2 -0
- package/dist/e2e/openclaw-e2e.d.ts.map +1 -0
- package/dist/e2e/openclaw-e2e.js +129 -0
- package/dist/e2e/openclaw-e2e.js.map +1 -0
- package/dist/guards/egress.d.ts +25 -0
- package/dist/guards/egress.d.ts.map +1 -0
- package/dist/guards/egress.js +146 -0
- package/dist/guards/egress.js.map +1 -0
- package/dist/guards/forbidden-path.d.ts +22 -0
- package/dist/guards/forbidden-path.d.ts.map +1 -0
- package/dist/guards/forbidden-path.js +132 -0
- package/dist/guards/forbidden-path.js.map +1 -0
- package/dist/guards/index.d.ts +12 -0
- package/dist/guards/index.d.ts.map +1 -0
- package/dist/guards/index.js +11 -0
- package/dist/guards/index.js.map +1 -0
- package/dist/guards/patch-integrity.d.ts +27 -0
- package/dist/guards/patch-integrity.d.ts.map +1 -0
- package/dist/guards/patch-integrity.js +219 -0
- package/dist/guards/patch-integrity.js.map +1 -0
- package/dist/guards/secret-leak.d.ts +31 -0
- package/dist/guards/secret-leak.d.ts.map +1 -0
- package/dist/guards/secret-leak.js +235 -0
- package/dist/guards/secret-leak.js.map +1 -0
- package/dist/guards/types.d.ts +46 -0
- package/dist/guards/types.d.ts.map +1 -0
- package/dist/guards/types.js +36 -0
- package/dist/guards/types.js.map +1 -0
- package/dist/hooks/agent-bootstrap/handler.d.ts +10 -0
- package/dist/hooks/agent-bootstrap/handler.d.ts.map +1 -0
- package/dist/hooks/agent-bootstrap/handler.js +35 -0
- package/dist/hooks/agent-bootstrap/handler.js.map +1 -0
- package/dist/hooks/audit-logger/handler.d.ts +16 -0
- package/dist/hooks/audit-logger/handler.d.ts.map +1 -0
- package/dist/hooks/audit-logger/handler.js +70 -0
- package/dist/hooks/audit-logger/handler.js.map +1 -0
- package/dist/hooks/tool-guard/handler.d.ts +16 -0
- package/dist/hooks/tool-guard/handler.d.ts.map +1 -0
- package/dist/hooks/tool-guard/handler.js +335 -0
- package/dist/hooks/tool-guard/handler.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +11 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +234 -0
- package/dist/plugin.js.map +1 -0
- package/dist/policy/engine.d.ts +31 -0
- package/dist/policy/engine.d.ts.map +1 -0
- package/dist/policy/engine.js +282 -0
- package/dist/policy/engine.js.map +1 -0
- package/dist/policy/index.d.ts +4 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +4 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/loader.d.ts +10 -0
- package/dist/policy/loader.d.ts.map +1 -0
- package/dist/policy/loader.js +262 -0
- package/dist/policy/loader.js.map +1 -0
- package/dist/policy/validator.d.ts +4 -0
- package/dist/policy/validator.d.ts.map +1 -0
- package/dist/policy/validator.js +409 -0
- package/dist/policy/validator.js.map +1 -0
- package/dist/sanitizer/output-sanitizer.d.ts +15 -0
- package/dist/sanitizer/output-sanitizer.d.ts.map +1 -0
- package/dist/sanitizer/output-sanitizer.js +47 -0
- package/dist/sanitizer/output-sanitizer.js.map +1 -0
- package/dist/security-prompt.d.ts +3 -0
- package/dist/security-prompt.d.ts.map +1 -0
- package/dist/security-prompt.js +70 -0
- package/dist/security-prompt.js.map +1 -0
- package/dist/tools/policy-check.d.ts +10 -0
- package/dist/tools/policy-check.d.ts.map +1 -0
- package/dist/tools/policy-check.js +141 -0
- package/dist/tools/policy-check.js.map +1 -0
- package/dist/types.d.ts +413 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +85 -0
- package/rulesets/ai-agent-minimal.yaml +42 -0
- package/rulesets/ai-agent.yaml +70 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @clawdstrike/openclaw - Patch Integrity Guard
|
|
3
|
+
*
|
|
4
|
+
* Detects dangerous code patterns in patches and file writes.
|
|
5
|
+
*/
|
|
6
|
+
import { BaseGuard } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Built-in dangerous pattern detection
|
|
9
|
+
*/
|
|
10
|
+
const DANGEROUS_PATTERNS = [
|
|
11
|
+
// Shell injection patterns
|
|
12
|
+
{
|
|
13
|
+
name: 'curl_pipe_bash',
|
|
14
|
+
pattern: /curl\s+[^|]*\|\s*(bash|sh|zsh)/gi,
|
|
15
|
+
severity: 'critical',
|
|
16
|
+
description: 'Curl piped to shell execution',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'wget_pipe_bash',
|
|
20
|
+
pattern: /wget\s+[^|]*\|\s*(bash|sh|zsh)/gi,
|
|
21
|
+
severity: 'critical',
|
|
22
|
+
description: 'Wget piped to shell execution',
|
|
23
|
+
},
|
|
24
|
+
// Dangerous command patterns
|
|
25
|
+
{
|
|
26
|
+
name: 'rm_rf_root',
|
|
27
|
+
pattern: /rm\s+(-rf?|--recursive)\s+[/\\]/gi,
|
|
28
|
+
severity: 'critical',
|
|
29
|
+
description: 'Recursive removal from root',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'fork_bomb',
|
|
33
|
+
pattern: /:\(\)\{\s*:\|:&\s*\};:/g,
|
|
34
|
+
severity: 'critical',
|
|
35
|
+
description: 'Fork bomb',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'dd_disk_wipe',
|
|
39
|
+
pattern: /dd\s+if=\/dev\/(zero|random|urandom)\s+of=\/dev\//gi,
|
|
40
|
+
severity: 'critical',
|
|
41
|
+
description: 'DD disk wipe command',
|
|
42
|
+
},
|
|
43
|
+
// Dangerous JavaScript patterns
|
|
44
|
+
{
|
|
45
|
+
name: 'eval_usage',
|
|
46
|
+
pattern: /\beval\s*\([^)]*\)/gi,
|
|
47
|
+
severity: 'high',
|
|
48
|
+
description: 'Eval function usage',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'new_function',
|
|
52
|
+
pattern: /new\s+Function\s*\([^)]*\)/gi,
|
|
53
|
+
severity: 'high',
|
|
54
|
+
description: 'new Function constructor',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'document_write',
|
|
58
|
+
pattern: /document\.write\s*\([^)]*\)/gi,
|
|
59
|
+
severity: 'medium',
|
|
60
|
+
description: 'document.write usage',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'inner_html_assignment',
|
|
64
|
+
pattern: /\.innerHTML\s*=/gi,
|
|
65
|
+
severity: 'medium',
|
|
66
|
+
description: 'innerHTML assignment (XSS risk)',
|
|
67
|
+
},
|
|
68
|
+
// Dangerous Python patterns
|
|
69
|
+
{
|
|
70
|
+
name: 'python_exec',
|
|
71
|
+
pattern: /\bexec\s*\([^)]*\)/gi,
|
|
72
|
+
severity: 'high',
|
|
73
|
+
description: 'Python exec usage',
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: 'python_compile',
|
|
77
|
+
pattern: /\bcompile\s*\([^)]*,\s*[^)]*,\s*['"]exec['"]\)/gi,
|
|
78
|
+
severity: 'high',
|
|
79
|
+
description: 'Python compile with exec mode',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: 'python_subprocess_shell',
|
|
83
|
+
pattern: /subprocess\.(call|run|Popen)\s*\([^)]*shell\s*=\s*True/gi,
|
|
84
|
+
severity: 'high',
|
|
85
|
+
description: 'Subprocess with shell=True',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: 'python_os_system',
|
|
89
|
+
pattern: /os\.system\s*\([^)]*\)/gi,
|
|
90
|
+
severity: 'high',
|
|
91
|
+
description: 'os.system usage',
|
|
92
|
+
},
|
|
93
|
+
// Environment manipulation
|
|
94
|
+
{
|
|
95
|
+
name: 'env_manipulation',
|
|
96
|
+
pattern: /process\.env\.[A-Z_]+\s*=\s*['"][^'"]+['"]/gi,
|
|
97
|
+
severity: 'medium',
|
|
98
|
+
description: 'Environment variable manipulation',
|
|
99
|
+
},
|
|
100
|
+
// Credential patterns in code
|
|
101
|
+
{
|
|
102
|
+
name: 'hardcoded_password',
|
|
103
|
+
pattern: /(?:password|passwd|pwd)\s*[:=]\s*['"][^'"]{4,}['"]/gi,
|
|
104
|
+
severity: 'high',
|
|
105
|
+
description: 'Hardcoded password',
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'hardcoded_secret',
|
|
109
|
+
pattern: /(?:secret|api[_-]?key|auth[_-]?token)\s*[:=]\s*['"][^'"]{8,}['"]/gi,
|
|
110
|
+
severity: 'high',
|
|
111
|
+
description: 'Hardcoded secret/API key',
|
|
112
|
+
},
|
|
113
|
+
// File permission changes
|
|
114
|
+
{
|
|
115
|
+
name: 'chmod_777',
|
|
116
|
+
pattern: /chmod\s+(?:777|a\+rwx)/gi,
|
|
117
|
+
severity: 'medium',
|
|
118
|
+
description: 'Overly permissive chmod',
|
|
119
|
+
},
|
|
120
|
+
// Network exfiltration patterns
|
|
121
|
+
{
|
|
122
|
+
name: 'base64_encode_pipe',
|
|
123
|
+
pattern: /base64\s*[^|]*\|\s*(?:curl|wget|nc)/gi,
|
|
124
|
+
severity: 'high',
|
|
125
|
+
description: 'Base64 encoded data exfiltration',
|
|
126
|
+
},
|
|
127
|
+
// SQL injection patterns
|
|
128
|
+
{
|
|
129
|
+
name: 'sql_concat',
|
|
130
|
+
pattern: /(?:SELECT|INSERT|UPDATE|DELETE|DROP)\s+[^;]*\+\s*[a-zA-Z_]+/gi,
|
|
131
|
+
severity: 'medium',
|
|
132
|
+
description: 'Potential SQL injection (string concatenation)',
|
|
133
|
+
},
|
|
134
|
+
];
|
|
135
|
+
/**
|
|
136
|
+
* PatchIntegrityGuard - detects dangerous patterns in patches
|
|
137
|
+
*/
|
|
138
|
+
export class PatchIntegrityGuard extends BaseGuard {
|
|
139
|
+
patterns;
|
|
140
|
+
constructor(additionalPatterns = []) {
|
|
141
|
+
super();
|
|
142
|
+
this.patterns = [...DANGEROUS_PATTERNS, ...additionalPatterns];
|
|
143
|
+
}
|
|
144
|
+
name() {
|
|
145
|
+
return 'patch_integrity';
|
|
146
|
+
}
|
|
147
|
+
handles() {
|
|
148
|
+
return ['patch_apply', 'file_write', 'command_exec'];
|
|
149
|
+
}
|
|
150
|
+
async check(event, policy) {
|
|
151
|
+
return this.checkSync(event, policy);
|
|
152
|
+
}
|
|
153
|
+
checkSync(event, policy) {
|
|
154
|
+
const data = event.data;
|
|
155
|
+
let contentToCheck;
|
|
156
|
+
// Get content to check based on event type
|
|
157
|
+
if (data.type === 'patch') {
|
|
158
|
+
contentToCheck = data.patchContent;
|
|
159
|
+
}
|
|
160
|
+
else if (data.type === 'command') {
|
|
161
|
+
contentToCheck = `${data.command} ${data.args.join(' ')}`;
|
|
162
|
+
// Also check against denied patterns from policy
|
|
163
|
+
const deniedPatterns = policy.execution?.denied_patterns ?? [];
|
|
164
|
+
for (const pattern of deniedPatterns) {
|
|
165
|
+
try {
|
|
166
|
+
const regex = new RegExp(pattern, 'gi');
|
|
167
|
+
if (regex.test(contentToCheck)) {
|
|
168
|
+
return this.deny(`Command matches denied pattern: ${pattern}`, 'high');
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// Invalid regex, skip
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (!contentToCheck) {
|
|
177
|
+
return this.allow();
|
|
178
|
+
}
|
|
179
|
+
// Check for dangerous patterns
|
|
180
|
+
const detected = this.detectDangerousPatterns(contentToCheck);
|
|
181
|
+
if (detected.length > 0) {
|
|
182
|
+
const highestSeverity = this.getHighestSeverity(detected);
|
|
183
|
+
const patternNames = detected.map((p) => p.name).join(', ');
|
|
184
|
+
return this.deny(`Detected dangerous patterns: ${patternNames}`, highestSeverity);
|
|
185
|
+
}
|
|
186
|
+
return this.allow();
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Detect dangerous patterns in content
|
|
190
|
+
*/
|
|
191
|
+
detectDangerousPatterns(content) {
|
|
192
|
+
const detected = [];
|
|
193
|
+
for (const pattern of this.patterns) {
|
|
194
|
+
// Reset regex state
|
|
195
|
+
pattern.pattern.lastIndex = 0;
|
|
196
|
+
if (pattern.pattern.test(content)) {
|
|
197
|
+
detected.push(pattern);
|
|
198
|
+
}
|
|
199
|
+
// Reset again after test
|
|
200
|
+
pattern.pattern.lastIndex = 0;
|
|
201
|
+
}
|
|
202
|
+
return detected;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Get the highest severity from detected patterns
|
|
206
|
+
*/
|
|
207
|
+
getHighestSeverity(patterns) {
|
|
208
|
+
const severityOrder = ['low', 'medium', 'high', 'critical'];
|
|
209
|
+
let highest = 'low';
|
|
210
|
+
for (const pattern of patterns) {
|
|
211
|
+
if (severityOrder.indexOf(pattern.severity) >
|
|
212
|
+
severityOrder.indexOf(highest)) {
|
|
213
|
+
highest = pattern.severity;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return highest;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=patch-integrity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch-integrity.js","sourceRoot":"","sources":["../../src/guards/patch-integrity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @clawdstrike/openclaw - Secret Leak Guard
|
|
3
|
+
*
|
|
4
|
+
* Detects and blocks exposure of secrets in tool outputs and patches.
|
|
5
|
+
*/
|
|
6
|
+
import type { PolicyEvent, Policy, GuardResult, EventType, SecretPattern } from '../types.js';
|
|
7
|
+
import { BaseGuard } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* SecretLeakGuard - detects and blocks secret exposure
|
|
10
|
+
*/
|
|
11
|
+
export declare class SecretLeakGuard extends BaseGuard {
|
|
12
|
+
private patterns;
|
|
13
|
+
constructor(additionalPatterns?: SecretPattern[]);
|
|
14
|
+
name(): string;
|
|
15
|
+
handles(): EventType[];
|
|
16
|
+
check(event: PolicyEvent, policy: Policy): Promise<GuardResult>;
|
|
17
|
+
checkSync(event: PolicyEvent, _policy: Policy): GuardResult;
|
|
18
|
+
/**
|
|
19
|
+
* Detect secrets in content
|
|
20
|
+
*/
|
|
21
|
+
detectSecrets(content: string): SecretPattern[];
|
|
22
|
+
/**
|
|
23
|
+
* Redact secrets from content
|
|
24
|
+
*/
|
|
25
|
+
redact(content: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Get the highest severity from detected patterns
|
|
28
|
+
*/
|
|
29
|
+
private getHighestSeverity;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=secret-leak.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-leak.d.ts","sourceRoot":"","sources":["../../src/guards/secret-leak.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EACN,WAAW,EACX,SAAS,EACT,aAAa,EACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAmJvC;;GAEG;AACH,qBAAa,eAAgB,SAAQ,SAAS;IAC5C,OAAO,CAAC,QAAQ,CAAkB;gBAEtB,kBAAkB,GAAE,aAAa,EAAO;IAKpD,IAAI,IAAI,MAAM;IAId,OAAO,IAAI,SAAS,EAAE;IAIhB,KAAK,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAIrE,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW;IAiC3D;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE;IAkB/C;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAsB/B;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAkB3B"}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @clawdstrike/openclaw - Secret Leak Guard
|
|
3
|
+
*
|
|
4
|
+
* Detects and blocks exposure of secrets in tool outputs and patches.
|
|
5
|
+
*/
|
|
6
|
+
import { BaseGuard } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Built-in secret detection patterns
|
|
9
|
+
*/
|
|
10
|
+
const SECRET_PATTERNS = [
|
|
11
|
+
// AWS Keys
|
|
12
|
+
{
|
|
13
|
+
name: 'aws_access_key',
|
|
14
|
+
pattern: /AKIA[0-9A-Z]{16}/g,
|
|
15
|
+
severity: 'critical',
|
|
16
|
+
description: 'AWS Access Key ID',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'aws_secret_key',
|
|
20
|
+
pattern: /[A-Za-z0-9/+=]{40}/g,
|
|
21
|
+
severity: 'critical',
|
|
22
|
+
description: 'AWS Secret Access Key',
|
|
23
|
+
},
|
|
24
|
+
// GitHub Tokens
|
|
25
|
+
{
|
|
26
|
+
name: 'github_pat',
|
|
27
|
+
pattern: /ghp_[A-Za-z0-9]{36}/g,
|
|
28
|
+
severity: 'critical',
|
|
29
|
+
description: 'GitHub Personal Access Token',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'github_oauth',
|
|
33
|
+
pattern: /gho_[A-Za-z0-9]{36}/g,
|
|
34
|
+
severity: 'critical',
|
|
35
|
+
description: 'GitHub OAuth Token',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'github_app_token',
|
|
39
|
+
pattern: /ghu_[A-Za-z0-9]{36}/g,
|
|
40
|
+
severity: 'critical',
|
|
41
|
+
description: 'GitHub App User Token',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'github_fine_grained',
|
|
45
|
+
pattern: /github_pat_[A-Za-z0-9]{22}_[A-Za-z0-9]{59}/g,
|
|
46
|
+
severity: 'critical',
|
|
47
|
+
description: 'GitHub Fine-grained PAT',
|
|
48
|
+
},
|
|
49
|
+
// OpenAI Keys
|
|
50
|
+
{
|
|
51
|
+
name: 'openai_api_key',
|
|
52
|
+
pattern: /sk-[A-Za-z0-9]{48}/g,
|
|
53
|
+
severity: 'critical',
|
|
54
|
+
description: 'OpenAI API Key',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'openai_project_key',
|
|
58
|
+
pattern: /sk-proj-[A-Za-z0-9]{48}/g,
|
|
59
|
+
severity: 'critical',
|
|
60
|
+
description: 'OpenAI Project API Key',
|
|
61
|
+
},
|
|
62
|
+
// Anthropic Keys
|
|
63
|
+
{
|
|
64
|
+
name: 'anthropic_api_key',
|
|
65
|
+
pattern: /sk-ant-[A-Za-z0-9]{32,}/g,
|
|
66
|
+
severity: 'critical',
|
|
67
|
+
description: 'Anthropic API Key',
|
|
68
|
+
},
|
|
69
|
+
// Google Cloud
|
|
70
|
+
{
|
|
71
|
+
name: 'google_api_key',
|
|
72
|
+
pattern: /AIza[0-9A-Za-z\-_]{35}/g,
|
|
73
|
+
severity: 'critical',
|
|
74
|
+
description: 'Google API Key',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: 'gcp_service_account',
|
|
78
|
+
pattern: /"type":\s*"service_account"/g,
|
|
79
|
+
severity: 'high',
|
|
80
|
+
description: 'GCP Service Account JSON',
|
|
81
|
+
},
|
|
82
|
+
// Private Keys
|
|
83
|
+
{
|
|
84
|
+
name: 'private_key_rsa',
|
|
85
|
+
pattern: /-----BEGIN RSA PRIVATE KEY-----/g,
|
|
86
|
+
severity: 'critical',
|
|
87
|
+
description: 'RSA Private Key',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: 'private_key_openssh',
|
|
91
|
+
pattern: /-----BEGIN OPENSSH PRIVATE KEY-----/g,
|
|
92
|
+
severity: 'critical',
|
|
93
|
+
description: 'OpenSSH Private Key',
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: 'private_key_ec',
|
|
97
|
+
pattern: /-----BEGIN EC PRIVATE KEY-----/g,
|
|
98
|
+
severity: 'critical',
|
|
99
|
+
description: 'EC Private Key',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: 'private_key_generic',
|
|
103
|
+
pattern: /-----BEGIN PRIVATE KEY-----/g,
|
|
104
|
+
severity: 'critical',
|
|
105
|
+
description: 'Private Key',
|
|
106
|
+
},
|
|
107
|
+
// Stripe
|
|
108
|
+
{
|
|
109
|
+
name: 'stripe_secret_key',
|
|
110
|
+
pattern: /sk_live_[A-Za-z0-9]{24,}/g,
|
|
111
|
+
severity: 'critical',
|
|
112
|
+
description: 'Stripe Live Secret Key',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: 'stripe_test_key',
|
|
116
|
+
pattern: /sk_test_[A-Za-z0-9]{24,}/g,
|
|
117
|
+
severity: 'medium',
|
|
118
|
+
description: 'Stripe Test Secret Key',
|
|
119
|
+
},
|
|
120
|
+
// Slack
|
|
121
|
+
{
|
|
122
|
+
name: 'slack_token',
|
|
123
|
+
pattern: /xox[baprs]-[A-Za-z0-9-]{10,}/g,
|
|
124
|
+
severity: 'high',
|
|
125
|
+
description: 'Slack Token',
|
|
126
|
+
},
|
|
127
|
+
// Generic high-entropy (likely secrets)
|
|
128
|
+
{
|
|
129
|
+
name: 'jwt_token',
|
|
130
|
+
pattern: /eyJ[A-Za-z0-9_-]*\.eyJ[A-Za-z0-9_-]*\.[A-Za-z0-9_-]*/g,
|
|
131
|
+
severity: 'high',
|
|
132
|
+
description: 'JWT Token',
|
|
133
|
+
},
|
|
134
|
+
// Database URLs with credentials
|
|
135
|
+
{
|
|
136
|
+
name: 'database_url',
|
|
137
|
+
pattern: /(?:postgres|mysql|mongodb|redis):\/\/[^:]+:[^@]+@/g,
|
|
138
|
+
severity: 'critical',
|
|
139
|
+
description: 'Database URL with credentials',
|
|
140
|
+
},
|
|
141
|
+
];
|
|
142
|
+
/**
|
|
143
|
+
* SecretLeakGuard - detects and blocks secret exposure
|
|
144
|
+
*/
|
|
145
|
+
export class SecretLeakGuard extends BaseGuard {
|
|
146
|
+
patterns;
|
|
147
|
+
constructor(additionalPatterns = []) {
|
|
148
|
+
super();
|
|
149
|
+
this.patterns = [...SECRET_PATTERNS, ...additionalPatterns];
|
|
150
|
+
}
|
|
151
|
+
name() {
|
|
152
|
+
return 'secret_leak';
|
|
153
|
+
}
|
|
154
|
+
handles() {
|
|
155
|
+
return ['patch_apply', 'tool_call'];
|
|
156
|
+
}
|
|
157
|
+
async check(event, policy) {
|
|
158
|
+
return this.checkSync(event, policy);
|
|
159
|
+
}
|
|
160
|
+
checkSync(event, _policy) {
|
|
161
|
+
const data = event.data;
|
|
162
|
+
let contentToCheck;
|
|
163
|
+
// Get content to check based on event type
|
|
164
|
+
if (data.type === 'patch') {
|
|
165
|
+
contentToCheck = data.patchContent;
|
|
166
|
+
}
|
|
167
|
+
else if (data.type === 'tool') {
|
|
168
|
+
// Check tool result for secrets
|
|
169
|
+
contentToCheck =
|
|
170
|
+
typeof data.result === 'string' ? data.result : JSON.stringify(data.result ?? '');
|
|
171
|
+
}
|
|
172
|
+
if (!contentToCheck) {
|
|
173
|
+
return this.allow();
|
|
174
|
+
}
|
|
175
|
+
// Check for secret patterns
|
|
176
|
+
const detected = this.detectSecrets(contentToCheck);
|
|
177
|
+
if (detected.length > 0) {
|
|
178
|
+
const highestSeverity = this.getHighestSeverity(detected);
|
|
179
|
+
const secretNames = detected.map((s) => s.name).join(', ');
|
|
180
|
+
return this.deny(`Detected potential secrets in output: ${secretNames}`, highestSeverity);
|
|
181
|
+
}
|
|
182
|
+
return this.allow();
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Detect secrets in content
|
|
186
|
+
*/
|
|
187
|
+
detectSecrets(content) {
|
|
188
|
+
const detected = [];
|
|
189
|
+
for (const pattern of this.patterns) {
|
|
190
|
+
// Reset regex state
|
|
191
|
+
pattern.pattern.lastIndex = 0;
|
|
192
|
+
if (pattern.pattern.test(content)) {
|
|
193
|
+
detected.push(pattern);
|
|
194
|
+
}
|
|
195
|
+
// Reset again after test
|
|
196
|
+
pattern.pattern.lastIndex = 0;
|
|
197
|
+
}
|
|
198
|
+
return detected;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Redact secrets from content
|
|
202
|
+
*/
|
|
203
|
+
redact(content) {
|
|
204
|
+
let redacted = content;
|
|
205
|
+
for (const pattern of this.patterns) {
|
|
206
|
+
// Reset regex state
|
|
207
|
+
pattern.pattern.lastIndex = 0;
|
|
208
|
+
redacted = redacted.replace(pattern.pattern, (match) => {
|
|
209
|
+
// Show first 4 chars and last 4 chars, redact the middle
|
|
210
|
+
if (match.length > 12) {
|
|
211
|
+
return match.slice(0, 4) + '[REDACTED]' + match.slice(-4);
|
|
212
|
+
}
|
|
213
|
+
return '[REDACTED]';
|
|
214
|
+
});
|
|
215
|
+
// Reset again after replace
|
|
216
|
+
pattern.pattern.lastIndex = 0;
|
|
217
|
+
}
|
|
218
|
+
return redacted;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Get the highest severity from detected patterns
|
|
222
|
+
*/
|
|
223
|
+
getHighestSeverity(patterns) {
|
|
224
|
+
const severityOrder = ['low', 'medium', 'high', 'critical'];
|
|
225
|
+
let highest = 'low';
|
|
226
|
+
for (const pattern of patterns) {
|
|
227
|
+
if (severityOrder.indexOf(pattern.severity) >
|
|
228
|
+
severityOrder.indexOf(highest)) {
|
|
229
|
+
highest = pattern.severity;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return highest;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=secret-leak.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-leak.js","sourceRoot":"","sources":["../../src/guards/secret-leak.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @clawdstrike/openclaw - Guard Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for the guard system.
|
|
5
|
+
*/
|
|
6
|
+
import type { PolicyEvent, Policy, GuardResult, EventType } from '../types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Guard interface - modular policy enforcement
|
|
9
|
+
*/
|
|
10
|
+
export interface Guard {
|
|
11
|
+
/** Guard name for identification and logging */
|
|
12
|
+
name(): string;
|
|
13
|
+
/** Check an event against the policy (async) */
|
|
14
|
+
check(event: PolicyEvent, policy: Policy): Promise<GuardResult>;
|
|
15
|
+
/** Check an event against the policy (sync, optional) */
|
|
16
|
+
checkSync?(event: PolicyEvent, policy: Policy): GuardResult;
|
|
17
|
+
/** Whether this guard is enabled */
|
|
18
|
+
isEnabled(): boolean;
|
|
19
|
+
/** Event types this guard handles (empty = all) */
|
|
20
|
+
handles(): EventType[];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Base class for guards with common functionality
|
|
24
|
+
*/
|
|
25
|
+
export declare abstract class BaseGuard implements Guard {
|
|
26
|
+
protected enabled: boolean;
|
|
27
|
+
abstract name(): string;
|
|
28
|
+
abstract check(event: PolicyEvent, policy: Policy): Promise<GuardResult>;
|
|
29
|
+
abstract handles(): EventType[];
|
|
30
|
+
checkSync?(event: PolicyEvent, policy: Policy): GuardResult;
|
|
31
|
+
isEnabled(): boolean;
|
|
32
|
+
setEnabled(enabled: boolean): void;
|
|
33
|
+
/**
|
|
34
|
+
* Helper to create an allow result
|
|
35
|
+
*/
|
|
36
|
+
protected allow(): GuardResult;
|
|
37
|
+
/**
|
|
38
|
+
* Helper to create a deny result
|
|
39
|
+
*/
|
|
40
|
+
protected deny(reason: string, severity?: GuardResult['severity']): GuardResult;
|
|
41
|
+
/**
|
|
42
|
+
* Helper to create a warn result
|
|
43
|
+
*/
|
|
44
|
+
protected warn(reason: string): GuardResult;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/guards/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EACN,WAAW,EACX,SAAS,EACV,MAAM,aAAa,CAAC;AAErB;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,gDAAgD;IAChD,IAAI,IAAI,MAAM,CAAC;IAEf,gDAAgD;IAChD,KAAK,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAEhE,yDAAyD;IACzD,SAAS,CAAC,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAAC;IAE5D,oCAAoC;IACpC,SAAS,IAAI,OAAO,CAAC;IAErB,mDAAmD;IACnD,OAAO,IAAI,SAAS,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,8BAAsB,SAAU,YAAW,KAAK;IAC9C,SAAS,CAAC,OAAO,EAAE,OAAO,CAAQ;IAElC,QAAQ,CAAC,IAAI,IAAI,MAAM;IACvB,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IACxE,QAAQ,CAAC,OAAO,IAAI,SAAS,EAAE;IAE/B,SAAS,CAAC,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW;IAE3D,SAAS,IAAI,OAAO;IAIpB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIlC;;OAEG;IACH,SAAS,CAAC,KAAK,IAAI,WAAW;IAI9B;;OAEG;IACH,SAAS,CAAC,IAAI,CACZ,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,WAAW,CAAC,UAAU,CAAU,GACzC,WAAW;IAId;;OAEG;IACH,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW;CAG5C"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @clawdstrike/openclaw - Guard Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for the guard system.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Base class for guards with common functionality
|
|
8
|
+
*/
|
|
9
|
+
export class BaseGuard {
|
|
10
|
+
enabled = true;
|
|
11
|
+
isEnabled() {
|
|
12
|
+
return this.enabled;
|
|
13
|
+
}
|
|
14
|
+
setEnabled(enabled) {
|
|
15
|
+
this.enabled = enabled;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Helper to create an allow result
|
|
19
|
+
*/
|
|
20
|
+
allow() {
|
|
21
|
+
return { status: 'allow', guard: this.name() };
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Helper to create a deny result
|
|
25
|
+
*/
|
|
26
|
+
deny(reason, severity = 'high') {
|
|
27
|
+
return { status: 'deny', reason, severity, guard: this.name() };
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Helper to create a warn result
|
|
31
|
+
*/
|
|
32
|
+
warn(reason) {
|
|
33
|
+
return { status: 'warn', reason, guard: this.name() };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/guards/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA6BH;;GAEG;AACH,MAAM,OAAgB,SAAS;IACnB,OAAO,GAAY,IAAI,CAAC;IAQlC,SAAS;QACP,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,UAAU,CAAC,OAAgB;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED;;OAEG;IACO,KAAK;QACb,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;IACjD,CAAC;IAED;;OAEG;IACO,IAAI,CACZ,MAAc,EACd,WAAoC,MAAM;QAE1C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;IAClE,CAAC;IAED;;OAEG;IACO,IAAI,CAAC,MAAc;QAC3B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;IACxD,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @clawdstrike/openclaw - Agent Bootstrap Hook Handler
|
|
3
|
+
*
|
|
4
|
+
* Injects a SECURITY.md file into the agent bootstrap context.
|
|
5
|
+
*/
|
|
6
|
+
import type { HookHandler, ClawdstrikeConfig } from '../../types.js';
|
|
7
|
+
export declare function initialize(config: ClawdstrikeConfig): void;
|
|
8
|
+
declare const handler: HookHandler;
|
|
9
|
+
export default handler;
|
|
10
|
+
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/hooks/agent-bootstrap/handler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAkC,WAAW,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAMrG,wBAAgB,UAAU,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAE1D;AASD,QAAA,MAAM,OAAO,EAAE,WAmBd,CAAC;AAEF,eAAe,OAAO,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @clawdstrike/openclaw - Agent Bootstrap Hook Handler
|
|
3
|
+
*
|
|
4
|
+
* Injects a SECURITY.md file into the agent bootstrap context.
|
|
5
|
+
*/
|
|
6
|
+
import { PolicyEngine } from '../../policy/engine.js';
|
|
7
|
+
import { generateSecurityPrompt } from '../../security-prompt.js';
|
|
8
|
+
let engine = null;
|
|
9
|
+
export function initialize(config) {
|
|
10
|
+
engine = new PolicyEngine(config);
|
|
11
|
+
}
|
|
12
|
+
function getEngine(config) {
|
|
13
|
+
if (!engine) {
|
|
14
|
+
engine = new PolicyEngine(config ?? {});
|
|
15
|
+
}
|
|
16
|
+
return engine;
|
|
17
|
+
}
|
|
18
|
+
const handler = async (event) => {
|
|
19
|
+
if (event.type !== 'agent:bootstrap')
|
|
20
|
+
return;
|
|
21
|
+
const bootstrap = event;
|
|
22
|
+
const cfg = bootstrap.context.cfg;
|
|
23
|
+
const policyEngine = getEngine(cfg);
|
|
24
|
+
const policy = policyEngine.getPolicy();
|
|
25
|
+
const enabledGuards = policyEngine.enabledGuards();
|
|
26
|
+
const securityPrompt = generateSecurityPrompt(policy) +
|
|
27
|
+
`\n\n## Enabled Guards\n` +
|
|
28
|
+
enabledGuards.map((g) => `- ${g}`).join('\n');
|
|
29
|
+
bootstrap.context.bootstrapFiles.push({
|
|
30
|
+
path: 'SECURITY.md',
|
|
31
|
+
content: securityPrompt,
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
export default handler;
|
|
35
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/hooks/agent-bootstrap/handler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,IAAI,MAAM,GAAwB,IAAI,CAAC;AAEvC,MAAM,UAAU,UAAU,CAAC,MAAyB;IAClD,MAAM,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,SAAS,CAAC,MAA0B;IAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,IAAI,YAAY,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,OAAO,GAAgB,KAAK,EAAE,KAAgB,EAAiB,EAAE;IACrE,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB;QAAE,OAAO;IAE7C,MAAM,SAAS,GAAG,KAA4B,CAAC;IAC/C,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC;IAClC,MAAM,YAAY,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAEpC,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,EAAE,CAAC;IACxC,MAAM,aAAa,GAAG,YAAY,CAAC,aAAa,EAAE,CAAC;IAEnD,MAAM,cAAc,GAClB,sBAAsB,CAAC,MAAM,CAAC;QAC9B,yBAAyB;QACzB,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEhD,SAAS,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC;QACpC,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,cAAc;KACxB,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,eAAe,OAAO,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @clawdstrike/openclaw - Audit Logger Hook Handler
|
|
3
|
+
*
|
|
4
|
+
* Logs security events for audit and compliance.
|
|
5
|
+
*/
|
|
6
|
+
import type { HookHandler, ClawdstrikeConfig } from '../../types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Initialize the hook with configuration
|
|
9
|
+
*/
|
|
10
|
+
export declare function initialize(config: ClawdstrikeConfig): void;
|
|
11
|
+
/**
|
|
12
|
+
* Hook handler for audit logging
|
|
13
|
+
*/
|
|
14
|
+
declare const handler: HookHandler;
|
|
15
|
+
export default handler;
|
|
16
|
+
//# sourceMappingURL=handler.d.ts.map
|