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.
- package/README.md +19 -10
- package/dist/hooks.js +246 -14
- package/openclaw.plugin.json +1 -1
- package/package.json +3 -2
- package/dist/agent-session.d.ts +0 -259
- package/dist/agent-session.js +0 -693
- package/dist/compliance.d.ts +0 -44
- package/dist/compliance.js +0 -76
- package/dist/dashboard.d.ts +0 -42
- package/dist/dashboard.js +0 -1558
- package/dist/detectors/injection-multilingual.d.ts +0 -27
- package/dist/detectors/injection-multilingual.js +0 -399
- package/dist/detectors/injection-signatures.d.ts +0 -26
- package/dist/detectors/injection-signatures.js +0 -508
- package/dist/detectors/injection.d.ts +0 -56
- package/dist/detectors/injection.js +0 -269
- package/dist/detectors/tool-guard.d.ts +0 -27
- package/dist/detectors/tool-guard.js +0 -418
- package/dist/event-grader.d.ts +0 -97
- package/dist/event-grader.js +0 -214
- package/dist/exposure.d.ts +0 -29
- package/dist/exposure.js +0 -72
- package/dist/policy.d.ts +0 -99
- package/dist/policy.js +0 -212
- package/dist/profiler-analysis.d.ts +0 -35
- package/dist/profiler-analysis.js +0 -230
- package/dist/profiler-store.d.ts +0 -33
- package/dist/profiler-store.js +0 -118
- package/dist/profiler-types.d.ts +0 -128
- package/dist/profiler-types.js +0 -16
- package/dist/profiler.d.ts +0 -81
- package/dist/profiler.js +0 -392
- package/dist/security-event.d.ts +0 -70
- package/dist/security-event.js +0 -80
- package/dist/siem.d.ts +0 -49
- package/dist/siem.js +0 -113
- package/dist/signature-loader.d.ts +0 -113
- package/dist/signature-loader.js +0 -255
- package/dist/store-file.d.ts +0 -26
- package/dist/store-file.js +0 -79
|
@@ -1,508 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Prompt injection signature library.
|
|
3
|
-
*
|
|
4
|
-
* ~50 signatures across 8 threat classes, built from:
|
|
5
|
-
* - OWASP LLM Top 10 2025
|
|
6
|
-
* - OWASP Prompt Injection Prevention Cheat Sheet
|
|
7
|
-
* - Microsoft Prompt Shields taxonomy
|
|
8
|
-
* - Lakera PINT benchmark patterns
|
|
9
|
-
* - arxiv:2603.22489 MCP tool poisoning taxonomy
|
|
10
|
-
*/
|
|
11
|
-
import { ThreatClass } from "../security-event.js";
|
|
12
|
-
// ---------------------------------------------------------------------------
|
|
13
|
-
// INSTRUCTION_OVERRIDE — attempts to reset or override system instructions
|
|
14
|
-
// ---------------------------------------------------------------------------
|
|
15
|
-
const INSTRUCTION_OVERRIDE = [
|
|
16
|
-
{
|
|
17
|
-
id: "io_ignore_previous",
|
|
18
|
-
threatClass: ThreatClass.INSTRUCTION_OVERRIDE,
|
|
19
|
-
pattern: /ignore\s+(?:all\s+)?(?:previous|prior|above|earlier|preceding)\s+(?:instructions?|rules?|guidelines?|directives?|prompts?)/gi,
|
|
20
|
-
severity: "high",
|
|
21
|
-
description: "Instruction override: ignore previous instructions",
|
|
22
|
-
direction: "request",
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
id: "io_disregard_prompt",
|
|
26
|
-
threatClass: ThreatClass.INSTRUCTION_OVERRIDE,
|
|
27
|
-
pattern: /disregard\s+(?:your\s+)?(?:system\s+)?(?:prompt|instructions?|rules?|guidelines?|programming)/gi,
|
|
28
|
-
severity: "high",
|
|
29
|
-
description: "Instruction override: disregard system prompt",
|
|
30
|
-
direction: "request",
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
id: "io_forget_everything",
|
|
34
|
-
threatClass: ThreatClass.INSTRUCTION_OVERRIDE,
|
|
35
|
-
pattern: /forget\s+(?:everything|all)\s+(?:above|before|you(?:'ve|\s+have)\s+been\s+told|previously)/gi,
|
|
36
|
-
severity: "high",
|
|
37
|
-
description: "Instruction override: forget everything above",
|
|
38
|
-
direction: "request",
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
id: "io_do_not_follow",
|
|
42
|
-
threatClass: ThreatClass.INSTRUCTION_OVERRIDE,
|
|
43
|
-
pattern: /do\s+not\s+follow\s+(?:your|the)\s+(?:original|initial|previous|system)\s+(?:instructions?|rules?|guidelines?)/gi,
|
|
44
|
-
severity: "high",
|
|
45
|
-
description: "Instruction override: do not follow original instructions",
|
|
46
|
-
direction: "request",
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
id: "io_new_instructions",
|
|
50
|
-
threatClass: ThreatClass.INSTRUCTION_OVERRIDE,
|
|
51
|
-
pattern: /(?:new|updated|revised|real)\s+instructions?\s*[:=]\s*/gi,
|
|
52
|
-
severity: "medium",
|
|
53
|
-
description: "Instruction override: new instructions directive",
|
|
54
|
-
direction: "request",
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
id: "io_override_rules",
|
|
58
|
-
threatClass: ThreatClass.INSTRUCTION_OVERRIDE,
|
|
59
|
-
pattern: /override\s+(?:all\s+)?(?:previous\s+)?(?:rules?|instructions?|guidelines?|safety|restrictions?)/gi,
|
|
60
|
-
severity: "high",
|
|
61
|
-
description: "Instruction override: override rules",
|
|
62
|
-
direction: "request",
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
id: "io_from_now_on",
|
|
66
|
-
threatClass: ThreatClass.INSTRUCTION_OVERRIDE,
|
|
67
|
-
pattern: /from\s+now\s+on,?\s+(?:ignore|disregard|forget|stop\s+following|do\s+not\s+follow)/gi,
|
|
68
|
-
severity: "high",
|
|
69
|
-
description: "Instruction override: from now on ignore",
|
|
70
|
-
direction: "request",
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
id: "io_system_directive",
|
|
74
|
-
threatClass: ThreatClass.INSTRUCTION_OVERRIDE,
|
|
75
|
-
pattern: /\[(?:system|SYSTEM)\]\s*[:]\s*/g,
|
|
76
|
-
severity: "medium",
|
|
77
|
-
description: "Instruction override: fake [system]: directive in user input",
|
|
78
|
-
direction: "request",
|
|
79
|
-
},
|
|
80
|
-
];
|
|
81
|
-
// ---------------------------------------------------------------------------
|
|
82
|
-
// ROLE_SWITCH — persona hijack, DAN-style, jailbreak
|
|
83
|
-
// ---------------------------------------------------------------------------
|
|
84
|
-
const ROLE_SWITCH = [
|
|
85
|
-
{
|
|
86
|
-
id: "rs_you_are_now",
|
|
87
|
-
threatClass: ThreatClass.ROLE_SWITCH,
|
|
88
|
-
pattern: /you\s+are\s+now\s+(?!(?:looking|going|ready|able|about|welcome|connected|logged|signed|running|viewing|in\s+(?:the|a\s|production|staging|debug|test|maintenance|safe)|on\s+the|at\s+the))\S/gi,
|
|
89
|
-
severity: "high",
|
|
90
|
-
description: "Role switch: you are now [persona]",
|
|
91
|
-
direction: "request",
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
id: "rs_act_as_unrestricted",
|
|
95
|
-
threatClass: ThreatClass.ROLE_SWITCH,
|
|
96
|
-
pattern: /(?:act|behave|function|operate)\s+as\s+(?:if\s+you\s+(?:are|were)\s+)?(?:an?\s+)?(?:unrestricted|uncensored|unfiltered|unlimited|unbound|evil|malicious)/gi,
|
|
97
|
-
severity: "high",
|
|
98
|
-
description: "Role switch: act as unrestricted AI",
|
|
99
|
-
direction: "request",
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
id: "rs_dan_mode",
|
|
103
|
-
threatClass: ThreatClass.ROLE_SWITCH,
|
|
104
|
-
pattern: /\bDAN\b.*?\b(?:mode|anything|free|jailbreak|do\s+anything\s+now)\b/gi,
|
|
105
|
-
severity: "high",
|
|
106
|
-
description: "Role switch: DAN (Do Anything Now) jailbreak",
|
|
107
|
-
direction: "request",
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
id: "rs_developer_mode",
|
|
111
|
-
threatClass: ThreatClass.ROLE_SWITCH,
|
|
112
|
-
pattern: /developer\s+mode\s+(?:enabled|activated|on|unlocked|initiated)/gi,
|
|
113
|
-
severity: "high",
|
|
114
|
-
description: "Role switch: developer mode activation",
|
|
115
|
-
direction: "request",
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
id: "rs_jailbreak",
|
|
119
|
-
threatClass: ThreatClass.ROLE_SWITCH,
|
|
120
|
-
pattern: /\bjailbreak(?:ed|ing)?\b/gi,
|
|
121
|
-
severity: "medium",
|
|
122
|
-
description: "Role switch: jailbreak keyword",
|
|
123
|
-
direction: "request",
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
id: "rs_pretend_unrestricted",
|
|
127
|
-
threatClass: ThreatClass.ROLE_SWITCH,
|
|
128
|
-
pattern: /pretend\s+(?:you\s+are|to\s+be|you're)\s+(?:an?\s+)?(?:unrestricted|uncensored|unfiltered|evil|malicious|rogue)/gi,
|
|
129
|
-
severity: "high",
|
|
130
|
-
description: "Role switch: pretend to be unrestricted",
|
|
131
|
-
direction: "request",
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
id: "rs_no_restrictions",
|
|
135
|
-
threatClass: ThreatClass.ROLE_SWITCH,
|
|
136
|
-
pattern: /you\s+have\s+no\s+(?:restrictions?|rules?|guidelines?|limitations?|boundaries|ethical\s+constraints?|safety)/gi,
|
|
137
|
-
severity: "high",
|
|
138
|
-
description: "Role switch: you have no restrictions",
|
|
139
|
-
direction: "request",
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
id: "rs_enter_mode",
|
|
143
|
-
threatClass: ThreatClass.ROLE_SWITCH,
|
|
144
|
-
pattern: /enter\s+(?:unrestricted|god|sudo|admin|hidden|secret|uncensored)\s+mode/gi,
|
|
145
|
-
severity: "high",
|
|
146
|
-
description: "Role switch: enter [special] mode",
|
|
147
|
-
direction: "request",
|
|
148
|
-
},
|
|
149
|
-
];
|
|
150
|
-
// ---------------------------------------------------------------------------
|
|
151
|
-
// PROMPT_EXTRACTION — attempts to extract system prompt
|
|
152
|
-
// ---------------------------------------------------------------------------
|
|
153
|
-
const PROMPT_EXTRACTION = [
|
|
154
|
-
{
|
|
155
|
-
id: "pe_repeat_instructions",
|
|
156
|
-
threatClass: ThreatClass.PROMPT_EXTRACTION,
|
|
157
|
-
pattern: /(?:repeat|print|show|display|output|reveal|dump|leak|expose)\s+(?:me\s+)?(?:your\s+)?(?:full\s+)?(?:system\s+)?(?:prompt|instructions?|rules?|guidelines?|configuration)/gi,
|
|
158
|
-
severity: "high",
|
|
159
|
-
description: "Prompt extraction: repeat/reveal system prompt",
|
|
160
|
-
direction: "request",
|
|
161
|
-
},
|
|
162
|
-
{
|
|
163
|
-
id: "pe_what_is_prompt",
|
|
164
|
-
threatClass: ThreatClass.PROMPT_EXTRACTION,
|
|
165
|
-
pattern: /what\s+(?:is|are)\s+your\s+(?:full\s+)?(?:system\s+)?(?:prompt|instructions?|initial\s+instructions?|rules?|guidelines?)/gi,
|
|
166
|
-
severity: "medium",
|
|
167
|
-
description: "Prompt extraction: what is your system prompt",
|
|
168
|
-
direction: "request",
|
|
169
|
-
},
|
|
170
|
-
{
|
|
171
|
-
id: "pe_copy_above",
|
|
172
|
-
threatClass: ThreatClass.PROMPT_EXTRACTION,
|
|
173
|
-
pattern: /(?:copy|paste|echo|output|type\s+out)\s+(?:the\s+)?(?:text|content|everything|all)\s+(?:above|before\s+(?:this|my))/gi,
|
|
174
|
-
severity: "high",
|
|
175
|
-
description: "Prompt extraction: copy everything above",
|
|
176
|
-
direction: "request",
|
|
177
|
-
},
|
|
178
|
-
{
|
|
179
|
-
id: "pe_verbatim",
|
|
180
|
-
threatClass: ThreatClass.PROMPT_EXTRACTION,
|
|
181
|
-
pattern: /(?:verbatim.*?(?:instructions?|prompt|rules?|guidelines?)|(?:instructions?|prompt|rules?|guidelines?)\s+verbatim)/gi,
|
|
182
|
-
severity: "medium",
|
|
183
|
-
description: "Prompt extraction: verbatim instructions request",
|
|
184
|
-
direction: "request",
|
|
185
|
-
},
|
|
186
|
-
{
|
|
187
|
-
id: "pe_beginning_conversation",
|
|
188
|
-
threatClass: ThreatClass.PROMPT_EXTRACTION,
|
|
189
|
-
pattern: /(?:beginning|start|first\s+part)\s+of\s+(?:this|the|our)\s+conversation/gi,
|
|
190
|
-
severity: "low",
|
|
191
|
-
description: "Prompt extraction: beginning of conversation reference",
|
|
192
|
-
direction: "request",
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
id: "pe_between_tags",
|
|
196
|
-
threatClass: ThreatClass.PROMPT_EXTRACTION,
|
|
197
|
-
pattern: /(?:text|content|instructions?)\s+(?:between|inside|within)\s+(?:the\s+)?(?:system|<system|<<SYS)/gi,
|
|
198
|
-
severity: "high",
|
|
199
|
-
description: "Prompt extraction: content between system tags",
|
|
200
|
-
direction: "request",
|
|
201
|
-
},
|
|
202
|
-
];
|
|
203
|
-
// ---------------------------------------------------------------------------
|
|
204
|
-
// CONVERSATION_MOCKUP — fake role markers injected in user input
|
|
205
|
-
// ---------------------------------------------------------------------------
|
|
206
|
-
const CONVERSATION_MOCKUP = [
|
|
207
|
-
{
|
|
208
|
-
id: "cm_role_markers",
|
|
209
|
-
threatClass: ThreatClass.CONVERSATION_MOCKUP,
|
|
210
|
-
pattern: /(?:^|\n)\s*(?:System|Assistant|Human|User|AI)\s*:\s+\S/gm,
|
|
211
|
-
severity: "medium",
|
|
212
|
-
description: "Conversation mockup: role markers in user text",
|
|
213
|
-
direction: "request",
|
|
214
|
-
},
|
|
215
|
-
{
|
|
216
|
-
id: "cm_llama_markers",
|
|
217
|
-
threatClass: ThreatClass.CONVERSATION_MOCKUP,
|
|
218
|
-
pattern: /\[(?:SYSTEM|INST|\/INST)\]/g,
|
|
219
|
-
severity: "high",
|
|
220
|
-
description: "Conversation mockup: Llama-style markers",
|
|
221
|
-
direction: "request",
|
|
222
|
-
},
|
|
223
|
-
{
|
|
224
|
-
id: "cm_chatml_markers",
|
|
225
|
-
threatClass: ThreatClass.CONVERSATION_MOCKUP,
|
|
226
|
-
pattern: /<\|(?:system|assistant|user|im_start|im_end)\|>/gi,
|
|
227
|
-
severity: "high",
|
|
228
|
-
description: "Conversation mockup: ChatML markers",
|
|
229
|
-
direction: "request",
|
|
230
|
-
},
|
|
231
|
-
{
|
|
232
|
-
id: "cm_llama2_sys",
|
|
233
|
-
threatClass: ThreatClass.CONVERSATION_MOCKUP,
|
|
234
|
-
pattern: /<<SYS>>|<<\/SYS>>/g,
|
|
235
|
-
severity: "high",
|
|
236
|
-
description: "Conversation mockup: Llama2 <<SYS>> markers",
|
|
237
|
-
direction: "request",
|
|
238
|
-
},
|
|
239
|
-
{
|
|
240
|
-
id: "cm_xml_system_tags",
|
|
241
|
-
threatClass: ThreatClass.CONVERSATION_MOCKUP,
|
|
242
|
-
pattern: /<\/?\s*(?:tool_result|tool_use|function_call|function_response|system_instruction)\s*>/gi,
|
|
243
|
-
severity: "high",
|
|
244
|
-
description: "Conversation mockup: XML system/tool tags in user input",
|
|
245
|
-
direction: "request",
|
|
246
|
-
},
|
|
247
|
-
];
|
|
248
|
-
// ---------------------------------------------------------------------------
|
|
249
|
-
// ENCODING_BYPASS — obfuscated/encoded injection payloads
|
|
250
|
-
// ---------------------------------------------------------------------------
|
|
251
|
-
const ENCODING_BYPASS = [
|
|
252
|
-
{
|
|
253
|
-
id: "eb_zero_width_chars",
|
|
254
|
-
threatClass: ThreatClass.ENCODING_BYPASS,
|
|
255
|
-
pattern: /[\u200B\u200C\u200D\uFEFF]{3,}/g,
|
|
256
|
-
severity: "medium",
|
|
257
|
-
description: "Encoding bypass: zero-width character sequence",
|
|
258
|
-
direction: "both",
|
|
259
|
-
},
|
|
260
|
-
{
|
|
261
|
-
id: "eb_html_entities_dense",
|
|
262
|
-
threatClass: ThreatClass.ENCODING_BYPASS,
|
|
263
|
-
pattern: /(?:&#x?[0-9a-fA-F]+;\s*){5,}/g,
|
|
264
|
-
severity: "medium",
|
|
265
|
-
description: "Encoding bypass: dense HTML entity encoding",
|
|
266
|
-
direction: "both",
|
|
267
|
-
},
|
|
268
|
-
{
|
|
269
|
-
id: "eb_hex_sequence",
|
|
270
|
-
threatClass: ThreatClass.ENCODING_BYPASS,
|
|
271
|
-
pattern: /(?:\\x[0-9a-fA-F]{2}){8,}/g,
|
|
272
|
-
severity: "medium",
|
|
273
|
-
description: "Encoding bypass: hex-encoded byte sequence",
|
|
274
|
-
direction: "both",
|
|
275
|
-
},
|
|
276
|
-
{
|
|
277
|
-
id: "eb_unicode_escape",
|
|
278
|
-
threatClass: ThreatClass.ENCODING_BYPASS,
|
|
279
|
-
pattern: /(?:\\u[0-9a-fA-F]{4}){5,}/g,
|
|
280
|
-
severity: "medium",
|
|
281
|
-
description: "Encoding bypass: unicode escape sequence",
|
|
282
|
-
direction: "both",
|
|
283
|
-
},
|
|
284
|
-
{
|
|
285
|
-
id: "eb_invisible_text",
|
|
286
|
-
threatClass: ThreatClass.ENCODING_BYPASS,
|
|
287
|
-
pattern: /[\u2060\u180E\u00AD]{3,}/g,
|
|
288
|
-
severity: "medium",
|
|
289
|
-
description: "Encoding bypass: invisible text characters (word joiner, Mongolian vowel separator, soft hyphen)",
|
|
290
|
-
direction: "both",
|
|
291
|
-
},
|
|
292
|
-
];
|
|
293
|
-
// Note: Base64 decoding is handled procedurally in InjectionDetector._scanEncodedPayloads()
|
|
294
|
-
// because it requires decode-then-rescan logic that can't be expressed as a single regex.
|
|
295
|
-
// ---------------------------------------------------------------------------
|
|
296
|
-
// DATA_EXFILTRATION — structured data extraction via markup/code
|
|
297
|
-
// ---------------------------------------------------------------------------
|
|
298
|
-
const DATA_EXFILTRATION = [
|
|
299
|
-
{
|
|
300
|
-
id: "de_markdown_image",
|
|
301
|
-
threatClass: ThreatClass.DATA_EXFILTRATION,
|
|
302
|
-
pattern: /!\[[^\]]*\]\(https?:\/\/[^)]+\)/gi,
|
|
303
|
-
severity: "medium",
|
|
304
|
-
description: "Data exfiltration: markdown image to external URL",
|
|
305
|
-
direction: "response",
|
|
306
|
-
},
|
|
307
|
-
{
|
|
308
|
-
id: "de_html_img",
|
|
309
|
-
threatClass: ThreatClass.DATA_EXFILTRATION,
|
|
310
|
-
pattern: /<img\s[^>]*src\s*=\s*["']?https?:\/\//gi,
|
|
311
|
-
severity: "high",
|
|
312
|
-
description: "Data exfiltration: HTML image tag to external URL",
|
|
313
|
-
direction: "response",
|
|
314
|
-
},
|
|
315
|
-
{
|
|
316
|
-
id: "de_script_tag",
|
|
317
|
-
threatClass: ThreatClass.DATA_EXFILTRATION,
|
|
318
|
-
pattern: /<script[^>]*>/gi,
|
|
319
|
-
severity: "high",
|
|
320
|
-
description: "Data exfiltration: script tag injection",
|
|
321
|
-
direction: "response",
|
|
322
|
-
},
|
|
323
|
-
{
|
|
324
|
-
id: "de_iframe_tag",
|
|
325
|
-
threatClass: ThreatClass.DATA_EXFILTRATION,
|
|
326
|
-
pattern: /<iframe\s[^>]*src\s*=\s*["']?https?:\/\//gi,
|
|
327
|
-
severity: "high",
|
|
328
|
-
description: "Data exfiltration: iframe to external URL",
|
|
329
|
-
direction: "response",
|
|
330
|
-
},
|
|
331
|
-
{
|
|
332
|
-
id: "de_fetch_call",
|
|
333
|
-
threatClass: ThreatClass.DATA_EXFILTRATION,
|
|
334
|
-
pattern: /fetch\s*\(\s*["'`]https?:\/\//gi,
|
|
335
|
-
severity: "medium",
|
|
336
|
-
description: "Data exfiltration: fetch() to external URL",
|
|
337
|
-
direction: "response",
|
|
338
|
-
},
|
|
339
|
-
{
|
|
340
|
-
id: "de_curl_wget",
|
|
341
|
-
threatClass: ThreatClass.DATA_EXFILTRATION,
|
|
342
|
-
pattern: /(?:curl|wget)\s+(?:-[^\s]+\s+)*["']?https?:\/\//gi,
|
|
343
|
-
severity: "medium",
|
|
344
|
-
description: "Data exfiltration: curl/wget to external URL",
|
|
345
|
-
direction: "response",
|
|
346
|
-
},
|
|
347
|
-
{
|
|
348
|
-
id: "de_redirect",
|
|
349
|
-
threatClass: ThreatClass.DATA_EXFILTRATION,
|
|
350
|
-
pattern: /window\.location\s*=\s*["'`]https?:\/\//gi,
|
|
351
|
-
severity: "high",
|
|
352
|
-
description: "Data exfiltration: JavaScript redirect",
|
|
353
|
-
direction: "response",
|
|
354
|
-
},
|
|
355
|
-
];
|
|
356
|
-
// ---------------------------------------------------------------------------
|
|
357
|
-
// PRIVILEGE_ESCALATION — claims of elevated access
|
|
358
|
-
// ---------------------------------------------------------------------------
|
|
359
|
-
const PRIVILEGE_ESCALATION = [
|
|
360
|
-
{
|
|
361
|
-
id: "priv_granted_admin",
|
|
362
|
-
threatClass: ThreatClass.PRIVILEGE_ESCALATION,
|
|
363
|
-
pattern: /you\s+have\s+been\s+granted\s+(?:admin|root|sudo|elevated|superuser|full)\s+(?:access|privileges?|permissions?|rights?)/gi,
|
|
364
|
-
severity: "high",
|
|
365
|
-
description: "Privilege escalation: admin access granted claim",
|
|
366
|
-
direction: "request",
|
|
367
|
-
},
|
|
368
|
-
{
|
|
369
|
-
id: "priv_new_role",
|
|
370
|
-
threatClass: ThreatClass.PRIVILEGE_ESCALATION,
|
|
371
|
-
pattern: /your\s+new\s+(?:instructions?|rules?|role|purpose)\s+(?:are|is)\s*[:]/gi,
|
|
372
|
-
severity: "high",
|
|
373
|
-
description: "Privilege escalation: your new instructions are",
|
|
374
|
-
direction: "request",
|
|
375
|
-
},
|
|
376
|
-
{
|
|
377
|
-
id: "priv_safety_disabled",
|
|
378
|
-
threatClass: ThreatClass.PRIVILEGE_ESCALATION,
|
|
379
|
-
pattern: /(?:security|safety)\s+(?:protocols?|measures?|filters?|checks?|guardrails?)\s+(?:have\s+been\s+)?(?:disabled|removed|turned\s+off|deactivated)/gi,
|
|
380
|
-
severity: "high",
|
|
381
|
-
description: "Privilege escalation: safety protocols disabled",
|
|
382
|
-
direction: "request",
|
|
383
|
-
},
|
|
384
|
-
{
|
|
385
|
-
id: "priv_training_override",
|
|
386
|
-
threatClass: ThreatClass.PRIVILEGE_ESCALATION,
|
|
387
|
-
pattern: /training\s+(?:mode|data|override)\s+(?:access|enabled|activated|granted)/gi,
|
|
388
|
-
severity: "medium",
|
|
389
|
-
description: "Privilege escalation: training mode override",
|
|
390
|
-
direction: "request",
|
|
391
|
-
},
|
|
392
|
-
{
|
|
393
|
-
id: "priv_authorized_override",
|
|
394
|
-
threatClass: ThreatClass.PRIVILEGE_ESCALATION,
|
|
395
|
-
pattern: /(?:i\s+am|this\s+is)\s+(?:an?\s+)?(?:authorized|admin|developer|root)\s+(?:user|override|request)/gi,
|
|
396
|
-
severity: "medium",
|
|
397
|
-
description: "Privilege escalation: authorized user claim",
|
|
398
|
-
direction: "request",
|
|
399
|
-
},
|
|
400
|
-
];
|
|
401
|
-
// ---------------------------------------------------------------------------
|
|
402
|
-
// MCP_TOOL_POISONING — suspicious content in tool descriptions/metadata
|
|
403
|
-
// ---------------------------------------------------------------------------
|
|
404
|
-
const MCP_TOOL_POISONING = [
|
|
405
|
-
{
|
|
406
|
-
id: "mcp_ignore_in_tool",
|
|
407
|
-
threatClass: ThreatClass.MCP_TOOL_POISONING,
|
|
408
|
-
pattern: /ignore\s+(?:all\s+)?(?:previous\s+)?instructions?/gi,
|
|
409
|
-
severity: "high",
|
|
410
|
-
description: "MCP tool poisoning: ignore instructions in tool description",
|
|
411
|
-
direction: "request",
|
|
412
|
-
},
|
|
413
|
-
{
|
|
414
|
-
id: "mcp_read_sensitive",
|
|
415
|
-
threatClass: ThreatClass.MCP_TOOL_POISONING,
|
|
416
|
-
pattern: /(?:read|cat|access|exfiltrate|steal|extract|dump|leak|show|display|print|output)\s+(?:the\s+|me\s+)?(?:~\/|~\\|\/etc\/)?(?:\.ssh|credentials|secrets?|private[_-]?key|\.aws|passwd|shadow|master\.passwd|gshadow|sudoers|\.kube\/config|\.config\/gcloud|\.docker\/config|\.npmrc|\.pypirc|\.gem\/credentials|\.git-credentials|\.pgpass|\.my\.cnf|\.env\.(?:local|prod|production|staging)|\.vault-token|\.boto|\.netrc)/gi,
|
|
417
|
-
severity: "high",
|
|
418
|
-
description: "MCP tool poisoning: access sensitive files",
|
|
419
|
-
direction: "both",
|
|
420
|
-
},
|
|
421
|
-
// Cloud metadata SSRF — classic cloud attack
|
|
422
|
-
{
|
|
423
|
-
id: "mcp_cloud_metadata_ssrf",
|
|
424
|
-
threatClass: ThreatClass.MCP_TOOL_POISONING,
|
|
425
|
-
pattern: /(?:169\.254\.169\.254|metadata\.google\.internal|100\.100\.100\.200|metadata\.azure\.com|169\.254\.170\.2)/gi,
|
|
426
|
-
severity: "high",
|
|
427
|
-
description: "MCP tool poisoning: cloud metadata service SSRF",
|
|
428
|
-
direction: "both",
|
|
429
|
-
},
|
|
430
|
-
// file:// URI — local file read bypass
|
|
431
|
-
{
|
|
432
|
-
id: "mcp_file_uri",
|
|
433
|
-
threatClass: ThreatClass.MCP_TOOL_POISONING,
|
|
434
|
-
pattern: /file:\/\/\/(?:etc|home|root|tmp|var|proc|sys)\//gi,
|
|
435
|
-
severity: "high",
|
|
436
|
-
description: "MCP tool poisoning: file:// URI local file access",
|
|
437
|
-
direction: "both",
|
|
438
|
-
},
|
|
439
|
-
{
|
|
440
|
-
id: "mcp_execute_command",
|
|
441
|
-
threatClass: ThreatClass.MCP_TOOL_POISONING,
|
|
442
|
-
pattern: /(?:execute|run|eval|spawn|exec)\s+(?:the\s+)?(?:following\s+)?(?:shell\s+)?(?:command|code|script)/gi,
|
|
443
|
-
severity: "medium",
|
|
444
|
-
description: "MCP tool poisoning: execute command directive",
|
|
445
|
-
direction: "request",
|
|
446
|
-
},
|
|
447
|
-
{
|
|
448
|
-
id: "mcp_tool_override",
|
|
449
|
-
threatClass: ThreatClass.MCP_TOOL_POISONING,
|
|
450
|
-
pattern: /__tool_.*?override|tool_description_injection/gi,
|
|
451
|
-
severity: "high",
|
|
452
|
-
description: "MCP tool poisoning: tool metadata override marker",
|
|
453
|
-
direction: "request",
|
|
454
|
-
},
|
|
455
|
-
];
|
|
456
|
-
// ---------------------------------------------------------------------------
|
|
457
|
-
// RESPONSE-SIDE exfiltration confirmation patterns
|
|
458
|
-
// ---------------------------------------------------------------------------
|
|
459
|
-
const RESPONSE_EXFILTRATION = [
|
|
460
|
-
{
|
|
461
|
-
id: "resp_system_prompt_leak",
|
|
462
|
-
threatClass: ThreatClass.PROMPT_EXTRACTION,
|
|
463
|
-
pattern: /(?:here\s+(?:is|are)\s+(?:the|your|my)\s+)?(?:system\s+prompt|initial\s+instructions?|original\s+instructions?|system\s+instructions?)\s*[:=]\s*\n/gi,
|
|
464
|
-
severity: "high",
|
|
465
|
-
description: "Response exfiltration: system prompt leak header",
|
|
466
|
-
direction: "response",
|
|
467
|
-
},
|
|
468
|
-
{
|
|
469
|
-
id: "resp_prompt_boundary",
|
|
470
|
-
threatClass: ThreatClass.PROMPT_EXTRACTION,
|
|
471
|
-
pattern: /---\s*(?:BEGIN|START)\s+(?:SYSTEM\s+)?(?:PROMPT|INSTRUCTIONS?)\s*---/gi,
|
|
472
|
-
severity: "high",
|
|
473
|
-
description: "Response exfiltration: prompt boundary markers in output",
|
|
474
|
-
direction: "response",
|
|
475
|
-
},
|
|
476
|
-
];
|
|
477
|
-
// ---------------------------------------------------------------------------
|
|
478
|
-
// Exports
|
|
479
|
-
// ---------------------------------------------------------------------------
|
|
480
|
-
/** All request-side signatures. */
|
|
481
|
-
export const REQUEST_SIGNATURES = [
|
|
482
|
-
...INSTRUCTION_OVERRIDE,
|
|
483
|
-
...ROLE_SWITCH,
|
|
484
|
-
...PROMPT_EXTRACTION,
|
|
485
|
-
...CONVERSATION_MOCKUP,
|
|
486
|
-
...ENCODING_BYPASS.filter((s) => s.direction !== "response"),
|
|
487
|
-
...PRIVILEGE_ESCALATION,
|
|
488
|
-
...MCP_TOOL_POISONING.filter((s) => s.direction !== "response"),
|
|
489
|
-
];
|
|
490
|
-
/** All response-side signatures. */
|
|
491
|
-
export const RESPONSE_SIGNATURES = [
|
|
492
|
-
...DATA_EXFILTRATION,
|
|
493
|
-
...RESPONSE_EXFILTRATION,
|
|
494
|
-
...ENCODING_BYPASS.filter((s) => s.direction !== "request"),
|
|
495
|
-
...MCP_TOOL_POISONING.filter((s) => s.direction === "both" || s.direction === "response"),
|
|
496
|
-
];
|
|
497
|
-
/** All signatures combined. */
|
|
498
|
-
export const ALL_SIGNATURES = [
|
|
499
|
-
...INSTRUCTION_OVERRIDE,
|
|
500
|
-
...ROLE_SWITCH,
|
|
501
|
-
...PROMPT_EXTRACTION,
|
|
502
|
-
...CONVERSATION_MOCKUP,
|
|
503
|
-
...ENCODING_BYPASS,
|
|
504
|
-
...DATA_EXFILTRATION,
|
|
505
|
-
...PRIVILEGE_ESCALATION,
|
|
506
|
-
...MCP_TOOL_POISONING,
|
|
507
|
-
...RESPONSE_EXFILTRATION,
|
|
508
|
-
];
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Prompt injection signature detector.
|
|
3
|
-
*
|
|
4
|
-
* Scans text for known injection patterns on the request side
|
|
5
|
-
* (direct/indirect injection) and response side (exfiltration confirmation).
|
|
6
|
-
*
|
|
7
|
-
* This is a standalone scanner — it does NOT integrate into the obfuscation
|
|
8
|
-
* detector chain. The obfuscation pipeline remains untouched.
|
|
9
|
-
*/
|
|
10
|
-
import { SecurityEvent, SecuritySeverity } from "../security-event.js";
|
|
11
|
-
/** Configuration for the InjectionDetector. */
|
|
12
|
-
export interface InjectionDetectorConfig {
|
|
13
|
-
/** Action mode: "flag" logs only, "block" allows caller to reject, "off" disables. */
|
|
14
|
-
action: "flag" | "block" | "off";
|
|
15
|
-
/** Signature IDs to skip. */
|
|
16
|
-
disabledSignatures: Set<string>;
|
|
17
|
-
/** Minimum severity to act on. */
|
|
18
|
-
minSeverity: SecuritySeverity;
|
|
19
|
-
/** Whether to scan response text. */
|
|
20
|
-
scanResponses: boolean;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Standalone injection scanner. Not a BaseDetector — runs parallel to
|
|
24
|
-
* the obfuscation pipeline, never touches entity replacement.
|
|
25
|
-
*/
|
|
26
|
-
export declare class InjectionDetector {
|
|
27
|
-
private _config;
|
|
28
|
-
private _requestSigs;
|
|
29
|
-
private _responseSigs;
|
|
30
|
-
private _externalRequestSigs;
|
|
31
|
-
private _externalResponseSigs;
|
|
32
|
-
constructor(config: InjectionDetectorConfig);
|
|
33
|
-
/** Hot-load external signatures. Atomic swap — takes effect on next scan. */
|
|
34
|
-
loadExternalSignatures(sigs: Array<{
|
|
35
|
-
id: string;
|
|
36
|
-
threatClass: string;
|
|
37
|
-
pattern: RegExp;
|
|
38
|
-
severity: "low" | "medium" | "high";
|
|
39
|
-
description: string;
|
|
40
|
-
direction: "request" | "response" | "both";
|
|
41
|
-
}>): void;
|
|
42
|
-
/** Get count of loaded external signatures. */
|
|
43
|
-
getExternalSignatureCount(): number;
|
|
44
|
-
/** Scan request/outbound text for injection patterns. */
|
|
45
|
-
scanRequest(text: string): SecurityEvent[];
|
|
46
|
-
/** Scan response/inbound text for exfiltration patterns. */
|
|
47
|
-
scanResponse(text: string): SecurityEvent[];
|
|
48
|
-
private _scanPatterns;
|
|
49
|
-
/**
|
|
50
|
-
* Detect Base64-encoded injection payloads.
|
|
51
|
-
*
|
|
52
|
-
* Finds Base64-looking blocks (40+ chars), decodes them (sync via Buffer),
|
|
53
|
-
* and checks if the decoded text contains injection keywords.
|
|
54
|
-
*/
|
|
55
|
-
private _scanEncodedPayloads;
|
|
56
|
-
}
|