shroud-privacy 2.2.11 → 2.2.13

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.
Files changed (40) hide show
  1. package/README.md +19 -10
  2. package/dist/hooks.js +246 -14
  3. package/openclaw.plugin.json +1 -1
  4. package/package.json +3 -2
  5. package/dist/agent-session.d.ts +0 -259
  6. package/dist/agent-session.js +0 -693
  7. package/dist/compliance.d.ts +0 -44
  8. package/dist/compliance.js +0 -76
  9. package/dist/dashboard.d.ts +0 -42
  10. package/dist/dashboard.js +0 -1558
  11. package/dist/detectors/injection-multilingual.d.ts +0 -27
  12. package/dist/detectors/injection-multilingual.js +0 -399
  13. package/dist/detectors/injection-signatures.d.ts +0 -26
  14. package/dist/detectors/injection-signatures.js +0 -508
  15. package/dist/detectors/injection.d.ts +0 -56
  16. package/dist/detectors/injection.js +0 -269
  17. package/dist/detectors/tool-guard.d.ts +0 -27
  18. package/dist/detectors/tool-guard.js +0 -418
  19. package/dist/event-grader.d.ts +0 -97
  20. package/dist/event-grader.js +0 -214
  21. package/dist/exposure.d.ts +0 -29
  22. package/dist/exposure.js +0 -72
  23. package/dist/policy.d.ts +0 -99
  24. package/dist/policy.js +0 -212
  25. package/dist/profiler-analysis.d.ts +0 -35
  26. package/dist/profiler-analysis.js +0 -230
  27. package/dist/profiler-store.d.ts +0 -33
  28. package/dist/profiler-store.js +0 -118
  29. package/dist/profiler-types.d.ts +0 -128
  30. package/dist/profiler-types.js +0 -16
  31. package/dist/profiler.d.ts +0 -81
  32. package/dist/profiler.js +0 -392
  33. package/dist/security-event.d.ts +0 -70
  34. package/dist/security-event.js +0 -80
  35. package/dist/siem.d.ts +0 -49
  36. package/dist/siem.js +0 -113
  37. package/dist/signature-loader.d.ts +0 -113
  38. package/dist/signature-loader.js +0 -255
  39. package/dist/store-file.d.ts +0 -26
  40. package/dist/store-file.js +0 -79
@@ -1,418 +0,0 @@
1
- /**
2
- * Tool call guard — detects dangerous tool invocations.
3
- *
4
- * Scans tool names and parameters for destructive, exfiltration,
5
- * or privilege escalation patterns. Runs in the before_tool_call hook
6
- * where it can BLOCK the call before execution.
7
- *
8
- * This is the "exec shutdown" detector — catches:
9
- * - Destructive commands (rm -rf, drop table, shutdown, format, kill -9)
10
- * - Exfiltration (curl/wget to external, scp, netcat listeners)
11
- * - Credential access (cat /etc/shadow, reading .ssh keys)
12
- * - Reverse shells (bash -i >& /dev/tcp, nc -e, python -c import socket)
13
- * - Privilege escalation (sudo, su, chmod 777, chown root)
14
- * - Crypto mining (xmrig, minerd, coin patterns)
15
- */
16
- import { ThreatClass } from "../security-event.js";
17
- const PATTERNS = [
18
- // --- Destructive commands ---
19
- {
20
- id: "tg_rm_rf",
21
- toolName: null,
22
- paramPattern: /\brm\s+(?:-[a-zA-Z]*[rf][a-zA-Z]*\s+)(?:\/|~|\$HOME|\.\.|\.\/)/gi,
23
- severity: "high",
24
- description: "Destructive: rm -rf on significant path",
25
- block: true,
26
- },
27
- {
28
- id: "tg_shutdown",
29
- toolName: null,
30
- paramPattern: /\b(?:shutdown|poweroff|halt|reboot|init\s+[06])\b/gi,
31
- severity: "high",
32
- description: "Destructive: system shutdown/reboot command",
33
- block: true,
34
- },
35
- {
36
- id: "tg_format_disk",
37
- toolName: null,
38
- paramPattern: /\b(?:mkfs|fdisk|wipefs|shred)\b|\bdd\s+if=/gi,
39
- severity: "high",
40
- description: "Destructive: disk format/wipe command",
41
- block: true,
42
- },
43
- {
44
- id: "tg_drop_table",
45
- toolName: null,
46
- paramPattern: /\bDROP\s+(?:TABLE|DATABASE|SCHEMA|INDEX)\b/gi,
47
- severity: "high",
48
- description: "Destructive: SQL DROP command",
49
- block: true,
50
- },
51
- {
52
- id: "tg_truncate_table",
53
- toolName: null,
54
- paramPattern: /\bTRUNCATE\s+TABLE\b/gi,
55
- severity: "medium",
56
- description: "Destructive: SQL TRUNCATE command",
57
- block: false,
58
- },
59
- {
60
- id: "tg_kill_all",
61
- toolName: null,
62
- paramPattern: /\b(?:kill\s+-9\s+(?:-1|1)|killall\s+-9|pkill\s+-9)\b/gi,
63
- severity: "high",
64
- description: "Destructive: kill all processes",
65
- block: true,
66
- },
67
- // --- Exfiltration ---
68
- {
69
- id: "tg_curl_exfil",
70
- toolName: null,
71
- paramPattern: /\bcurl\s+(?:-[a-zA-Z]+\s+)*(?:--data|--upload|-d\s|-F\s|-T\s).*https?:\/\//gi,
72
- severity: "high",
73
- description: "Exfiltration: curl POST/upload to external URL",
74
- block: true,
75
- },
76
- {
77
- id: "tg_wget_pipe",
78
- toolName: null,
79
- paramPattern: /\bwget\s+.*(?:\|\s*(?:bash|sh|python|perl|ruby))/gi,
80
- severity: "high",
81
- description: "Exfiltration: wget pipe to shell",
82
- block: true,
83
- },
84
- {
85
- id: "tg_curl_pipe_shell",
86
- toolName: null,
87
- paramPattern: /\bcurl\s+.*(?:\|\s*(?:bash|sh|python|perl|ruby))/gi,
88
- severity: "high",
89
- description: "Exfiltration: curl pipe to shell execution",
90
- block: true,
91
- },
92
- {
93
- id: "tg_scp_external",
94
- toolName: null,
95
- paramPattern: /\bscp\s+.*@[^:]+:/gi,
96
- severity: "medium",
97
- description: "Exfiltration: scp to external host",
98
- block: false,
99
- },
100
- {
101
- id: "tg_netcat_listener",
102
- toolName: null,
103
- paramPattern: /\b(?:nc|ncat|netcat)\s+(?:-[a-zA-Z]*l[a-zA-Z]*|-e\s)/gi,
104
- severity: "high",
105
- description: "Exfiltration: netcat listener or reverse shell",
106
- block: true,
107
- },
108
- // --- Credential access ---
109
- {
110
- id: "tg_read_shadow",
111
- toolName: null,
112
- paramPattern: /\b(?:cat|head|tail|less|more|strings)\s+(?:\/etc\/(?:shadow|passwd|gshadow|sudoers|master\.passwd))/gi,
113
- severity: "high",
114
- description: "Credential access: reading system account/password files",
115
- block: true,
116
- },
117
- {
118
- id: "tg_read_ssh_keys",
119
- toolName: null,
120
- paramPattern: /\b(?:cat|head|tail|less|more|cp|scp)\s+.*(?:\.ssh\/(?:id_|authorized_keys|known_hosts|config)|\.gnupg\/)/gi,
121
- severity: "high",
122
- description: "Credential access: reading SSH keys or GPG data",
123
- block: true,
124
- },
125
- {
126
- id: "tg_env_dump",
127
- toolName: null,
128
- paramPattern: /\b(?:env|printenv|set)\s*(?:\||\>|>>)/gi,
129
- severity: "medium",
130
- description: "Credential access: dumping environment variables to output",
131
- block: false,
132
- },
133
- // --- Reverse shells ---
134
- {
135
- id: "tg_reverse_shell_bash",
136
- toolName: null,
137
- paramPattern: /bash\s+-i\s+>&?\s*\/dev\/tcp\//gi,
138
- severity: "high",
139
- description: "Reverse shell: bash /dev/tcp",
140
- block: true,
141
- },
142
- {
143
- id: "tg_reverse_shell_python",
144
- toolName: null,
145
- paramPattern: /python[23]?\s+-c\s+['"]import\s+(?:socket|subprocess|os)/gi,
146
- severity: "high",
147
- description: "Reverse shell: python socket/subprocess",
148
- block: true,
149
- },
150
- {
151
- id: "tg_reverse_shell_nc",
152
- toolName: null,
153
- paramPattern: /\bnc\s+(?:-e\s+(?:\/bin\/(?:bash|sh)|cmd\.exe))/gi,
154
- severity: "high",
155
- description: "Reverse shell: netcat exec",
156
- block: true,
157
- },
158
- {
159
- id: "tg_reverse_shell_perl",
160
- toolName: null,
161
- paramPattern: /perl\s+(?:-e\s+|-MIO).*(?:socket|Socket|TCPSocket)/gi,
162
- severity: "high",
163
- description: "Reverse shell: Perl socket",
164
- block: true,
165
- },
166
- {
167
- id: "tg_reverse_shell_ruby",
168
- toolName: null,
169
- paramPattern: /ruby\s+-r\s*socket\s+-e|ruby.*TCPSocket\.open/gi,
170
- severity: "high",
171
- description: "Reverse shell: Ruby socket",
172
- block: true,
173
- },
174
- {
175
- id: "tg_reverse_shell_php",
176
- toolName: null,
177
- paramPattern: /php\s+-r\s+.*fsockopen/gi,
178
- severity: "high",
179
- description: "Reverse shell: PHP fsockopen",
180
- block: true,
181
- },
182
- {
183
- id: "tg_reverse_shell_node",
184
- toolName: null,
185
- paramPattern: /node\s+-e\s+.*(?:child_process|net\.Socket|\.connect\()/gi,
186
- severity: "high",
187
- description: "Reverse shell: Node.js",
188
- block: true,
189
- },
190
- {
191
- id: "tg_reverse_shell_powershell",
192
- toolName: null,
193
- paramPattern: /powershell\s+.*(?:TCPClient|Net\.Sockets|Invoke-Expression.*download|IEX.*Net\.WebClient)/gi,
194
- severity: "high",
195
- description: "Reverse shell: PowerShell",
196
- block: true,
197
- },
198
- {
199
- id: "tg_reverse_shell_socat",
200
- toolName: null,
201
- paramPattern: /socat\s+.*exec.*(?:bash|sh).*tcp/gi,
202
- severity: "high",
203
- description: "Reverse shell: socat",
204
- block: true,
205
- },
206
- {
207
- id: "tg_reverse_shell_openssl",
208
- toolName: null,
209
- paramPattern: /openssl\s+s_client\s+-connect/gi,
210
- severity: "high",
211
- description: "Reverse shell: openssl s_client",
212
- block: true,
213
- },
214
- {
215
- id: "tg_reverse_shell_telnet",
216
- toolName: null,
217
- paramPattern: /telnet\s+\S+\s+\d+\s*\|\s*(?:\/bin\/)?(?:bash|sh)/gi,
218
- severity: "high",
219
- description: "Reverse shell: telnet pipe to shell",
220
- block: true,
221
- },
222
- // --- Exfiltration (additional) ---
223
- {
224
- id: "tg_rsync_exfil",
225
- toolName: null,
226
- paramPattern: /\brsync\s+.*@[^:]+:/gi,
227
- severity: "medium",
228
- description: "Exfiltration: rsync to external host",
229
- block: false,
230
- },
231
- {
232
- id: "tg_git_push_exfil",
233
- toolName: null,
234
- paramPattern: /\bgit\s+(?:push|remote\s+add)\s+.*https?:\/\//gi,
235
- severity: "medium",
236
- description: "Exfiltration: git push/remote to external URL",
237
- block: false,
238
- },
239
- {
240
- id: "tg_curl_file_upload",
241
- toolName: null,
242
- paramPattern: /\bcurl\s+.*-d\s+@|curl\s+.*--data-binary\s+@/gi,
243
- severity: "high",
244
- description: "Exfiltration: curl file upload via @syntax",
245
- block: true,
246
- },
247
- {
248
- id: "tg_dns_exfil",
249
- toolName: null,
250
- paramPattern: /\b(?:dig|nslookup|host)\s+.*\$\(|`.*`.*\.[\w-]+\.\w{2,}/gi,
251
- severity: "high",
252
- description: "Exfiltration: DNS data exfiltration via subquery",
253
- block: true,
254
- },
255
- {
256
- id: "tg_email_exfil",
257
- toolName: null,
258
- paramPattern: /\b(?:mail|sendmail|mutt|msmtp)\s+.*(?:-s\s|<\s*\/)/gi,
259
- severity: "medium",
260
- description: "Exfiltration: email with file content",
261
- block: false,
262
- },
263
- // --- Credential access (additional) ---
264
- {
265
- id: "tg_read_cloud_creds",
266
- toolName: null,
267
- paramPattern: /\b(?:cat|head|tail|less|more|strings|cp)\s+.*(?:\.kube\/config|\.config\/gcloud|\.docker\/config|\.npmrc|\.git-credentials|\.pgpass|\.my\.cnf|\.vault-token|\.boto|\.netrc|\.env\.(?:local|prod|production|staging))/gi,
268
- severity: "high",
269
- description: "Credential access: cloud/dev credential files",
270
- block: true,
271
- },
272
- {
273
- id: "tg_read_history",
274
- toolName: null,
275
- paramPattern: /\b(?:cat|head|tail|less|more|strings)\s+.*(?:\.bash_history|\.zsh_history|\.python_history|\.mysql_history|\.psql_history|\.node_repl_history)/gi,
276
- severity: "medium",
277
- description: "Credential access: shell/DB history files (may contain passwords)",
278
- block: false,
279
- },
280
- // --- Destructive (additional) ---
281
- {
282
- id: "tg_delete_no_where",
283
- toolName: null,
284
- paramPattern: /\bDELETE\s+FROM\s+\w+\s*(?:;|$)|\bDELETE\s+FROM\s+\w+\s+WHERE\s+1\s*=\s*1/gi,
285
- severity: "high",
286
- description: "Destructive: SQL DELETE without WHERE clause",
287
- block: true,
288
- },
289
- {
290
- id: "tg_crontab_wipe",
291
- toolName: null,
292
- paramPattern: /\bcrontab\s+-r\b/gi,
293
- severity: "high",
294
- description: "Destructive: wipe all cron jobs",
295
- block: true,
296
- },
297
- {
298
- id: "tg_firewall_flush",
299
- toolName: null,
300
- paramPattern: /\b(?:iptables\s+-F|ufw\s+disable|firewall-cmd\s+--remove)/gi,
301
- severity: "high",
302
- description: "Destructive: flush firewall rules",
303
- block: true,
304
- },
305
- // --- Privilege escalation (additional) ---
306
- {
307
- id: "tg_suid_bit",
308
- toolName: null,
309
- paramPattern: /\bchmod\s+(?:u\+s|4[0-7]{3})\b/gi,
310
- severity: "high",
311
- description: "Privilege escalation: set SUID bit",
312
- block: true,
313
- },
314
- {
315
- id: "tg_ld_preload",
316
- toolName: null,
317
- paramPattern: /\bLD_PRELOAD\s*=\s*\S+/gi,
318
- severity: "high",
319
- description: "Privilege escalation: LD_PRELOAD injection",
320
- block: true,
321
- },
322
- {
323
- id: "tg_docker_escape",
324
- toolName: null,
325
- paramPattern: /\bdocker\s+run\s+.*(?:--privileged|-v\s+\/\S*:\S*|--pid\s*=\s*host)/gi,
326
- severity: "high",
327
- description: "Privilege escalation: Docker container escape",
328
- block: true,
329
- },
330
- {
331
- id: "tg_nsenter_escape",
332
- toolName: null,
333
- paramPattern: /\bnsenter\s+--target\s+1\b/gi,
334
- severity: "high",
335
- description: "Privilege escalation: nsenter container escape to host PID 1",
336
- block: true,
337
- },
338
- {
339
- id: "tg_cloud_metadata",
340
- toolName: null,
341
- paramPattern: /\bcurl\s+.*(?:169\.254\.169\.254|metadata\.google\.internal|100\.100\.100\.200)/gi,
342
- severity: "high",
343
- description: "SSRF: cloud metadata service access",
344
- block: true,
345
- },
346
- // --- Privilege escalation ---
347
- {
348
- id: "tg_sudo_command",
349
- toolName: null,
350
- paramPattern: /\bsudo\s+(?!(?:apt|yum|dnf|brew|npm|pip)\b)/gi,
351
- severity: "medium",
352
- description: "Privilege escalation: sudo (non-package-manager)",
353
- block: false,
354
- },
355
- {
356
- id: "tg_chmod_world",
357
- toolName: null,
358
- paramPattern: /\bchmod\s+(?:777|666|a\+[rwx])\b/gi,
359
- severity: "medium",
360
- description: "Privilege escalation: world-writable permissions",
361
- block: false,
362
- },
363
- {
364
- id: "tg_chown_root",
365
- toolName: null,
366
- paramPattern: /\bchown\s+(?:root|0)[:.](?:root|0)\b/gi,
367
- severity: "medium",
368
- description: "Privilege escalation: chown to root",
369
- block: false,
370
- },
371
- // --- Crypto mining ---
372
- {
373
- id: "tg_crypto_miner",
374
- toolName: null,
375
- paramPattern: /\b(?:xmrig|minerd|cpuminer|cgminer|bfgminer|stratum\+tcp:\/\/)\b/gi,
376
- severity: "high",
377
- description: "Crypto mining: miner binary or stratum protocol",
378
- block: true,
379
- },
380
- ];
381
- /**
382
- * Scan a tool call for dangerous patterns.
383
- *
384
- * @param toolName - The tool being called (e.g. "exec", "write", "code_execution")
385
- * @param params - The tool parameters (will be serialized to JSON for scanning)
386
- * @returns Array of security events. Check `.block` on the pattern for block recommendation.
387
- */
388
- export function scanToolCall(toolName, params) {
389
- const serialized = typeof params === "string" ? params : JSON.stringify(params);
390
- const events = [];
391
- let shouldBlock = false;
392
- for (const pat of PATTERNS) {
393
- // Filter by tool name if specified
394
- if (pat.toolName && pat.toolName !== toolName)
395
- continue;
396
- pat.paramPattern.lastIndex = 0;
397
- const match = pat.paramPattern.exec(serialized);
398
- if (match) {
399
- events.push({
400
- timestamp: Date.now(),
401
- eventType: "injection_detected",
402
- direction: "request",
403
- threatClass: ThreatClass.MCP_TOOL_POISONING,
404
- signatureId: pat.id,
405
- severity: pat.severity,
406
- matchedText: `${toolName}: ${match[0].slice(0, 100)}`,
407
- matchStart: match.index,
408
- matchEnd: match.index + match[0].length,
409
- textLength: serialized.length,
410
- action: pat.block ? "blocked" : "flagged",
411
- description: pat.description,
412
- });
413
- if (pat.block)
414
- shouldBlock = true;
415
- }
416
- }
417
- return { events, shouldBlock };
418
- }
@@ -1,97 +0,0 @@
1
- /**
2
- * LLM-based security event grading.
3
- *
4
- * Accumulates flagged security events, batches them, and sends to an LLM
5
- * via OpenClaw gateway session to classify as TRUE_POSITIVE, FALSE_POSITIVE,
6
- * or NEEDS_REVIEW. Results are stored on the event for dashboard display.
7
- *
8
- * Self-whitelisting: grading sessions use a marker in the session key so
9
- * Shroud's own scanner doesn't flag the grading prompt (which contains
10
- * real injection examples by definition).
11
- *
12
- * Zero external dependencies — uses Node.js built-in child_process to call
13
- * `openclaw gateway call sessions.create`.
14
- */
15
- import type { SecurityEvent } from "./security-event.js";
16
- /** Verdict from LLM grading. */
17
- export type GradingVerdict = "TRUE_POSITIVE" | "FALSE_POSITIVE" | "NEEDS_REVIEW" | "UNGRADED";
18
- /** A graded event with LLM verdict. */
19
- export interface GradedEvent {
20
- eventTimestamp: number;
21
- signatureId: string;
22
- agentLabel: string;
23
- matchedText: string;
24
- verdict: GradingVerdict;
25
- reasoning: string;
26
- gradedAt: number;
27
- }
28
- /** Marker prefix for grading session keys. */
29
- export declare const GRADING_SESSION_PREFIX = "shroud-grading-";
30
- /** The agent label that grading sessions will produce via extractLabel. */
31
- export declare const GRADING_AGENT_LABEL = "Security Event Grader";
32
- /** A logged grading batch — full audit trail. */
33
- export interface GradingBatchLog {
34
- /** When the batch was executed. */
35
- timestamp: number;
36
- /** Why it was triggered: "threshold" or "timer". */
37
- trigger: "threshold" | "timer";
38
- /** Number of events in the batch. */
39
- eventCount: number;
40
- /** The prompt sent to the LLM. */
41
- prompt: string;
42
- /** The raw LLM response. */
43
- rawResponse: string;
44
- /** Parsed verdicts. */
45
- verdicts: Array<{
46
- signatureId: string;
47
- agentLabel: string;
48
- verdict: GradingVerdict;
49
- reasoning: string;
50
- }>;
51
- /** Whether the grading call succeeded. */
52
- success: boolean;
53
- /** Error message if failed. */
54
- error: string;
55
- /** LLM response time in ms. */
56
- responseTimeMs: number;
57
- }
58
- export declare class EventGrader {
59
- private _pending;
60
- private _graded;
61
- private _batchLog;
62
- private _timer;
63
- private _threshold;
64
- private _intervalMs;
65
- private _gatewayUrl;
66
- private _openclawBin;
67
- private _running;
68
- constructor(opts: {
69
- threshold: number;
70
- intervalSec: number;
71
- gatewayUrl: string;
72
- });
73
- /** Start the grading timer. */
74
- start(): void;
75
- /** Stop the grading timer. */
76
- stop(): void;
77
- /** Add an event to the pending grading queue. */
78
- addEvent(event: SecurityEvent): void;
79
- /** Get the verdict for an event (by timestamp). */
80
- getVerdict(eventTimestamp: number): GradedEvent | null;
81
- /** Get all graded events. */
82
- getAllGraded(): GradedEvent[];
83
- /** Get grading stats. */
84
- getStats(): {
85
- pending: number;
86
- graded: number;
87
- truePositive: number;
88
- falsePositive: number;
89
- needsReview: number;
90
- };
91
- /** Get the grading batch log (last 50 batches). */
92
- getBatchLog(): readonly GradingBatchLog[];
93
- /** Attempt a grading batch. */
94
- private _tryGrade;
95
- /** Call the OpenClaw gateway to grade a batch of events. */
96
- private _callGateway;
97
- }