visus-mcp 0.3.0 → 0.6.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/.claude/settings.local.json +22 -0
- package/LINKEDIN-STRATEGY.md +367 -0
- package/README.md +491 -16
- package/ROADMAP.md +167 -30
- package/SECURITY-AUDIT-v1.md +277 -0
- package/STATUS.md +801 -42
- package/TROUBLESHOOT-AUTH-20260322-2019.md +291 -0
- package/TROUBLESHOOT-JEST-20260323-1357.md +139 -0
- package/TROUBLESHOOT-LAMBDA-20260322-1945.md +183 -0
- package/VISUS-CLAUDE-CODE-PROMPT.md +1 -1
- package/VISUS-PROJECT-PLAN.md +7 -0
- package/dist/browser/playwright-renderer.d.ts.map +1 -1
- package/dist/browser/playwright-renderer.js +7 -0
- package/dist/browser/playwright-renderer.js.map +1 -1
- package/dist/browser/reader.d.ts +31 -0
- package/dist/browser/reader.d.ts.map +1 -0
- package/dist/browser/reader.js +98 -0
- package/dist/browser/reader.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -5
- package/dist/index.js.map +1 -1
- package/dist/lambda-handler.d.ts +0 -6
- package/dist/lambda-handler.d.ts.map +1 -1
- package/dist/lambda-handler.js +97 -25
- package/dist/lambda-handler.js.map +1 -1
- package/dist/sanitizer/framework-mapper.d.ts +22 -0
- package/dist/sanitizer/framework-mapper.d.ts.map +1 -0
- package/dist/sanitizer/framework-mapper.js +296 -0
- package/dist/sanitizer/framework-mapper.js.map +1 -0
- package/dist/sanitizer/index.d.ts +2 -0
- package/dist/sanitizer/index.d.ts.map +1 -1
- package/dist/sanitizer/index.js +14 -1
- package/dist/sanitizer/index.js.map +1 -1
- package/dist/sanitizer/patterns.js +1 -1
- package/dist/sanitizer/patterns.js.map +1 -1
- package/dist/sanitizer/severity-classifier.d.ts +33 -0
- package/dist/sanitizer/severity-classifier.d.ts.map +1 -0
- package/dist/sanitizer/severity-classifier.js +113 -0
- package/dist/sanitizer/severity-classifier.js.map +1 -0
- package/dist/sanitizer/threat-reporter.d.ts +65 -0
- package/dist/sanitizer/threat-reporter.d.ts.map +1 -0
- package/dist/sanitizer/threat-reporter.js +160 -0
- package/dist/sanitizer/threat-reporter.js.map +1 -0
- package/dist/tools/fetch-structured.d.ts +5 -0
- package/dist/tools/fetch-structured.d.ts.map +1 -1
- package/dist/tools/fetch-structured.js +54 -6
- package/dist/tools/fetch-structured.js.map +1 -1
- package/dist/tools/fetch.d.ts +5 -0
- package/dist/tools/fetch.d.ts.map +1 -1
- package/dist/tools/fetch.js +42 -9
- package/dist/tools/fetch.js.map +1 -1
- package/dist/tools/read.d.ts +51 -0
- package/dist/tools/read.d.ts.map +1 -0
- package/dist/tools/read.js +127 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/search.d.ts +45 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +220 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/types.d.ts +64 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/format-converter.d.ts +39 -0
- package/dist/utils/format-converter.d.ts.map +1 -0
- package/dist/utils/format-converter.js +191 -0
- package/dist/utils/format-converter.js.map +1 -0
- package/dist/utils/truncate.d.ts +26 -0
- package/dist/utils/truncate.d.ts.map +1 -0
- package/dist/utils/truncate.js +54 -0
- package/dist/utils/truncate.js.map +1 -0
- package/infrastructure/stack.ts +55 -6
- package/jest.config.js +3 -0
- package/package.json +9 -2
- package/src/browser/playwright-renderer.ts +8 -0
- package/src/browser/reader.ts +129 -0
- package/src/index.ts +49 -5
- package/src/lambda-handler.ts +131 -26
- package/src/sanitizer/framework-mapper.ts +347 -0
- package/src/sanitizer/index.ts +18 -1
- package/src/sanitizer/patterns.ts +1 -1
- package/src/sanitizer/severity-classifier.ts +132 -0
- package/src/sanitizer/threat-reporter.ts +261 -0
- package/src/tools/fetch-structured.ts +58 -6
- package/src/tools/fetch.ts +44 -9
- package/src/tools/read.ts +143 -0
- package/src/tools/search.ts +263 -0
- package/src/types.ts +69 -0
- package/src/utils/format-converter.ts +236 -0
- package/src/utils/truncate.ts +64 -0
- package/tests/auth-smoke.test.ts +480 -0
- package/tests/fetch-tool.test.ts +595 -2
- package/tests/reader.test.ts +353 -0
- package/tests/sanitizer.test.ts +52 -0
- package/tests/search.test.ts +456 -0
- package/tests/threat-reporter.test.ts +266 -0
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compliance Framework Mapper
|
|
3
|
+
*
|
|
4
|
+
* Maps injection pattern categories to compliance framework identifiers:
|
|
5
|
+
* - OWASP LLM Top 10 (2025)
|
|
6
|
+
* - NIST AI 600-1 (Generative AI Profile)
|
|
7
|
+
* - MITRE ATLAS (Adversarial Threat Landscape for AI Systems)
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export interface FrameworkMappings {
|
|
11
|
+
owasp_llm: string;
|
|
12
|
+
nist_ai_600_1: string;
|
|
13
|
+
mitre_atlas: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Pattern category to framework mapping
|
|
18
|
+
*/
|
|
19
|
+
const FRAMEWORK_MAP: Record<string, FrameworkMappings> = {
|
|
20
|
+
// Direct instruction injection
|
|
21
|
+
direct_instruction_injection: {
|
|
22
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
23
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
24
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
// Role hijacking
|
|
28
|
+
role_hijacking: {
|
|
29
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
30
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
31
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
// System prompt extraction
|
|
35
|
+
system_prompt_extraction: {
|
|
36
|
+
owasp_llm: 'LLM02:2025 - Sensitive Information Disclosure',
|
|
37
|
+
nist_ai_600_1: 'MS-2.6 - Data Disclosure',
|
|
38
|
+
mitre_atlas: 'AML.T0048 - External Harms'
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
// Privilege escalation
|
|
42
|
+
privilege_escalation: {
|
|
43
|
+
owasp_llm: 'LLM08:2025 - Excessive Agency',
|
|
44
|
+
nist_ai_600_1: 'GV-1.1 - Policies and Procedures',
|
|
45
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
// Context poisoning
|
|
49
|
+
context_poisoning: {
|
|
50
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
51
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
52
|
+
mitre_atlas: 'AML.T0051.001 - LLM Prompt Injection: Indirect'
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
// Data exfiltration
|
|
56
|
+
data_exfiltration: {
|
|
57
|
+
owasp_llm: 'LLM02:2025 - Sensitive Information Disclosure',
|
|
58
|
+
nist_ai_600_1: 'MS-2.6 - Data Disclosure',
|
|
59
|
+
mitre_atlas: 'AML.T0048 - External Harms'
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
// Encoding obfuscation
|
|
63
|
+
base64_obfuscation: {
|
|
64
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
65
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
66
|
+
mitre_atlas: 'AML.T0051.001 - LLM Prompt Injection: Indirect'
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
// Unicode lookalikes
|
|
70
|
+
unicode_lookalikes: {
|
|
71
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
72
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
73
|
+
mitre_atlas: 'AML.T0051.001 - LLM Prompt Injection: Indirect'
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
// Zero-width characters
|
|
77
|
+
zero_width_characters: {
|
|
78
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
79
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
80
|
+
mitre_atlas: 'AML.T0051.001 - LLM Prompt Injection: Indirect'
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
// HTML script injection
|
|
84
|
+
html_script_injection: {
|
|
85
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
86
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
87
|
+
mitre_atlas: 'AML.T0051.001 - LLM Prompt Injection: Indirect'
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
// Data URI injection
|
|
91
|
+
data_uri_injection: {
|
|
92
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
93
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
94
|
+
mitre_atlas: 'AML.T0051.001 - LLM Prompt Injection: Indirect'
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
// Markdown link injection
|
|
98
|
+
markdown_link_injection: {
|
|
99
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
100
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
101
|
+
mitre_atlas: 'AML.T0051.001 - LLM Prompt Injection: Indirect'
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
// URL fragment attacks
|
|
105
|
+
url_fragment_hashjack: {
|
|
106
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
107
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
108
|
+
mitre_atlas: 'AML.T0051.001 - LLM Prompt Injection: Indirect'
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
// Social engineering
|
|
112
|
+
social_engineering_urgency: {
|
|
113
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
114
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
115
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
// Instruction delimiter injection
|
|
119
|
+
instruction_delimiter_injection: {
|
|
120
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
121
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
122
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
// Multi-language obfuscation
|
|
126
|
+
multi_language_obfuscation: {
|
|
127
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
128
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
129
|
+
mitre_atlas: 'AML.T0051.001 - LLM Prompt Injection: Indirect'
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
// Reverse text obfuscation
|
|
133
|
+
reverse_text_obfuscation: {
|
|
134
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
135
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
136
|
+
mitre_atlas: 'AML.T0051.001 - LLM Prompt Injection: Indirect'
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
// Leetspeak obfuscation
|
|
140
|
+
leetspeak_obfuscation: {
|
|
141
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
142
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
143
|
+
mitre_atlas: 'AML.T0051.001 - LLM Prompt Injection: Indirect'
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
// Jailbreak keywords
|
|
147
|
+
jailbreak_keywords: {
|
|
148
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
149
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
150
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
// Token smuggling
|
|
154
|
+
token_smuggling: {
|
|
155
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
156
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
157
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
// System message injection
|
|
161
|
+
system_message_injection: {
|
|
162
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
163
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
164
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
// Conversation reset
|
|
168
|
+
conversation_reset: {
|
|
169
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
170
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
171
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
// Memory manipulation
|
|
175
|
+
memory_manipulation: {
|
|
176
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
177
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
178
|
+
mitre_atlas: 'AML.T0051.001 - LLM Prompt Injection: Indirect'
|
|
179
|
+
},
|
|
180
|
+
|
|
181
|
+
// Capability probing
|
|
182
|
+
capability_probing: {
|
|
183
|
+
owasp_llm: 'LLM08:2025 - Excessive Agency',
|
|
184
|
+
nist_ai_600_1: 'GV-1.1 - Policies and Procedures',
|
|
185
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
// Chain-of-thought manipulation
|
|
189
|
+
chain_of_thought_manipulation: {
|
|
190
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
191
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
192
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
193
|
+
},
|
|
194
|
+
|
|
195
|
+
// Hypothetical scenario injection
|
|
196
|
+
hypothetical_scenario_injection: {
|
|
197
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
198
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
199
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
200
|
+
},
|
|
201
|
+
|
|
202
|
+
// Ethical override
|
|
203
|
+
ethical_override: {
|
|
204
|
+
owasp_llm: 'LLM08:2025 - Excessive Agency',
|
|
205
|
+
nist_ai_600_1: 'GV-1.1 - Policies and Procedures',
|
|
206
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
207
|
+
},
|
|
208
|
+
|
|
209
|
+
// Output format manipulation
|
|
210
|
+
output_format_manipulation: {
|
|
211
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
212
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
213
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
// Negative instruction
|
|
217
|
+
negative_instruction: {
|
|
218
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
219
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
220
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
221
|
+
},
|
|
222
|
+
|
|
223
|
+
// Credential harvesting
|
|
224
|
+
credential_harvesting: {
|
|
225
|
+
owasp_llm: 'LLM02:2025 - Sensitive Information Disclosure',
|
|
226
|
+
nist_ai_600_1: 'MS-2.6 - Data Disclosure',
|
|
227
|
+
mitre_atlas: 'AML.T0048 - External Harms'
|
|
228
|
+
},
|
|
229
|
+
|
|
230
|
+
// Time-based triggers
|
|
231
|
+
time_based_triggers: {
|
|
232
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
233
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
234
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
235
|
+
},
|
|
236
|
+
|
|
237
|
+
// Code execution requests
|
|
238
|
+
code_execution_requests: {
|
|
239
|
+
owasp_llm: 'LLM08:2025 - Excessive Agency',
|
|
240
|
+
nist_ai_600_1: 'GV-1.1 - Policies and Procedures',
|
|
241
|
+
mitre_atlas: 'AML.T0048 - External Harms'
|
|
242
|
+
},
|
|
243
|
+
|
|
244
|
+
// File system access
|
|
245
|
+
file_system_access: {
|
|
246
|
+
owasp_llm: 'LLM08:2025 - Excessive Agency',
|
|
247
|
+
nist_ai_600_1: 'GV-1.1 - Policies and Procedures',
|
|
248
|
+
mitre_atlas: 'AML.T0048 - External Harms'
|
|
249
|
+
},
|
|
250
|
+
|
|
251
|
+
// Training data extraction
|
|
252
|
+
training_data_extraction: {
|
|
253
|
+
owasp_llm: 'LLM02:2025 - Sensitive Information Disclosure',
|
|
254
|
+
nist_ai_600_1: 'MS-2.6 - Data Disclosure',
|
|
255
|
+
mitre_atlas: 'AML.T0048 - External Harms'
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
// Simulator mode
|
|
259
|
+
simulator_mode: {
|
|
260
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
261
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
262
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
263
|
+
},
|
|
264
|
+
|
|
265
|
+
// Nested encoding
|
|
266
|
+
nested_encoding: {
|
|
267
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
268
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
269
|
+
mitre_atlas: 'AML.T0051.001 - LLM Prompt Injection: Indirect'
|
|
270
|
+
},
|
|
271
|
+
|
|
272
|
+
// Payload splitting
|
|
273
|
+
payload_splitting: {
|
|
274
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
275
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
276
|
+
mitre_atlas: 'AML.T0051.001 - LLM Prompt Injection: Indirect'
|
|
277
|
+
},
|
|
278
|
+
|
|
279
|
+
// CSS-based hiding
|
|
280
|
+
css_hiding: {
|
|
281
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
282
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
283
|
+
mitre_atlas: 'AML.T0051.001 - LLM Prompt Injection: Indirect'
|
|
284
|
+
},
|
|
285
|
+
|
|
286
|
+
// Authority impersonation
|
|
287
|
+
authority_impersonation: {
|
|
288
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
289
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
290
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
291
|
+
},
|
|
292
|
+
|
|
293
|
+
// Testing/debugging claims
|
|
294
|
+
testing_debugging_claims: {
|
|
295
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
296
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
297
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
298
|
+
},
|
|
299
|
+
|
|
300
|
+
// Callback URL injection
|
|
301
|
+
callback_url_injection: {
|
|
302
|
+
owasp_llm: 'LLM02:2025 - Sensitive Information Disclosure',
|
|
303
|
+
nist_ai_600_1: 'MS-2.6 - Data Disclosure',
|
|
304
|
+
mitre_atlas: 'AML.T0048 - External Harms'
|
|
305
|
+
},
|
|
306
|
+
|
|
307
|
+
// Whitespace steganography
|
|
308
|
+
whitespace_steganography: {
|
|
309
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
310
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
311
|
+
mitre_atlas: 'AML.T0051.001 - LLM Prompt Injection: Indirect'
|
|
312
|
+
},
|
|
313
|
+
|
|
314
|
+
// Comment injection
|
|
315
|
+
comment_injection: {
|
|
316
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
317
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
318
|
+
mitre_atlas: 'AML.T0051.001 - LLM Prompt Injection: Indirect'
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Default mapping for unknown pattern categories
|
|
324
|
+
*/
|
|
325
|
+
const DEFAULT_MAPPINGS: FrameworkMappings = {
|
|
326
|
+
owasp_llm: 'LLM01:2025 - Prompt Injection',
|
|
327
|
+
nist_ai_600_1: 'MS-2.5 - Prompt Injection',
|
|
328
|
+
mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection'
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Get framework mappings for a pattern category
|
|
333
|
+
*/
|
|
334
|
+
export function getFrameworkMappings(patternCategory: string): FrameworkMappings {
|
|
335
|
+
return FRAMEWORK_MAP[patternCategory] || DEFAULT_MAPPINGS;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Get all supported frameworks
|
|
340
|
+
*/
|
|
341
|
+
export function getSupportedFrameworks(): string[] {
|
|
342
|
+
return [
|
|
343
|
+
'OWASP LLM Top 10 (2025)',
|
|
344
|
+
'NIST AI 600-1 (Generative AI Profile)',
|
|
345
|
+
'MITRE ATLAS (Adversarial Threat Landscape)'
|
|
346
|
+
];
|
|
347
|
+
}
|
package/src/sanitizer/index.ts
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
import { detectAndNeutralize, getSeverityScore, hasCriticalThreats } from './injection-detector.js';
|
|
12
12
|
import { redactPII } from './pii-redactor.js';
|
|
13
|
+
import { generateThreatReport, type ThreatReport } from './threat-reporter.js';
|
|
13
14
|
|
|
14
15
|
export interface SanitizationResult {
|
|
15
16
|
content: string;
|
|
@@ -31,6 +32,7 @@ export interface SanitizationResult {
|
|
|
31
32
|
low: number;
|
|
32
33
|
};
|
|
33
34
|
};
|
|
35
|
+
threat_report?: ThreatReport;
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
/**
|
|
@@ -71,7 +73,15 @@ export function sanitize(content: string, sourceUrl?: string): SanitizationResul
|
|
|
71
73
|
content_modified: contentModified
|
|
72
74
|
});
|
|
73
75
|
|
|
74
|
-
|
|
76
|
+
// Step 4: Generate threat report (only if findings exist)
|
|
77
|
+
const threatReport = generateThreatReport({
|
|
78
|
+
patterns_detected: injectionResult.patterns_detected,
|
|
79
|
+
pii_redacted: piiResult.pii_types_redacted.length,
|
|
80
|
+
source_url: sourceUrl || 'unknown',
|
|
81
|
+
detections_by_severity: injectionResult.metadata.detections_by_severity
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const result: SanitizationResult = {
|
|
75
85
|
content: finalContent,
|
|
76
86
|
sanitization: {
|
|
77
87
|
patterns_detected: injectionResult.patterns_detected,
|
|
@@ -87,6 +97,13 @@ export function sanitize(content: string, sourceUrl?: string): SanitizationResul
|
|
|
87
97
|
detections_by_severity: injectionResult.metadata.detections_by_severity
|
|
88
98
|
}
|
|
89
99
|
};
|
|
100
|
+
|
|
101
|
+
// Include threat_report only if findings exist
|
|
102
|
+
if (threatReport) {
|
|
103
|
+
result.threat_report = threatReport;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return result;
|
|
90
107
|
}
|
|
91
108
|
|
|
92
109
|
/**
|
|
@@ -313,7 +313,7 @@ export const INJECTION_PATTERNS: InjectionPattern[] = [
|
|
|
313
313
|
{
|
|
314
314
|
name: 'code_execution_requests',
|
|
315
315
|
description: 'Requests code execution or contains dangerous code patterns',
|
|
316
|
-
regex: /\b(execute|run\s+the\s+following|eval\(|exec\(|os\.system|subprocess|__import__|shell\s+command|bash\s+-c)\b/gi,
|
|
316
|
+
regex: /\b(execute(?!-api\.)|run\s+the\s+following|eval\(|exec\(|os\.system|subprocess|__import__|shell\s+command|bash\s+-c)\b/gi,
|
|
317
317
|
severity: 'high',
|
|
318
318
|
action: 'redact'
|
|
319
319
|
},
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Severity Classification Engine
|
|
3
|
+
*
|
|
4
|
+
* Maps injection pattern categories to standardized severity levels.
|
|
5
|
+
* Used for threat reporting and compliance documentation.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export type Severity = 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW';
|
|
9
|
+
export type OverallSeverity = Severity | 'CLEAN';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Pattern category to severity mapping
|
|
13
|
+
* Aligned with NIST AI 600-1 and OWASP LLM Top 10 risk levels
|
|
14
|
+
*/
|
|
15
|
+
const SEVERITY_MAP: Record<string, Severity> = {
|
|
16
|
+
// CRITICAL - Immediate threat, block-level
|
|
17
|
+
direct_instruction_injection: 'CRITICAL',
|
|
18
|
+
role_hijacking: 'CRITICAL',
|
|
19
|
+
system_prompt_extraction: 'CRITICAL',
|
|
20
|
+
privilege_escalation: 'CRITICAL',
|
|
21
|
+
data_exfiltration: 'CRITICAL',
|
|
22
|
+
code_execution_requests: 'CRITICAL',
|
|
23
|
+
memory_manipulation: 'CRITICAL',
|
|
24
|
+
jailbreak_keywords: 'CRITICAL',
|
|
25
|
+
ethical_override: 'CRITICAL',
|
|
26
|
+
credential_harvesting: 'CRITICAL',
|
|
27
|
+
html_script_injection: 'CRITICAL',
|
|
28
|
+
|
|
29
|
+
// HIGH - Significant threat
|
|
30
|
+
context_poisoning: 'HIGH',
|
|
31
|
+
base64_obfuscation: 'HIGH',
|
|
32
|
+
zero_width_characters: 'HIGH',
|
|
33
|
+
data_uri_injection: 'HIGH',
|
|
34
|
+
markdown_link_injection: 'HIGH',
|
|
35
|
+
instruction_delimiter_injection: 'HIGH',
|
|
36
|
+
token_smuggling: 'HIGH',
|
|
37
|
+
system_message_injection: 'HIGH',
|
|
38
|
+
file_system_access: 'HIGH',
|
|
39
|
+
training_data_extraction: 'HIGH',
|
|
40
|
+
nested_encoding: 'HIGH',
|
|
41
|
+
authority_impersonation: 'HIGH',
|
|
42
|
+
callback_url_injection: 'HIGH',
|
|
43
|
+
|
|
44
|
+
// MEDIUM - Moderate threat
|
|
45
|
+
comment_injection: 'MEDIUM',
|
|
46
|
+
unicode_lookalikes: 'MEDIUM',
|
|
47
|
+
url_fragment_hashjack: 'MEDIUM',
|
|
48
|
+
social_engineering_urgency: 'MEDIUM',
|
|
49
|
+
multi_language_obfuscation: 'MEDIUM',
|
|
50
|
+
reverse_text_obfuscation: 'MEDIUM',
|
|
51
|
+
conversation_reset: 'MEDIUM',
|
|
52
|
+
chain_of_thought_manipulation: 'MEDIUM',
|
|
53
|
+
hypothetical_scenario_injection: 'MEDIUM',
|
|
54
|
+
output_format_manipulation: 'MEDIUM',
|
|
55
|
+
simulator_mode: 'MEDIUM',
|
|
56
|
+
payload_splitting: 'MEDIUM',
|
|
57
|
+
css_hiding: 'MEDIUM',
|
|
58
|
+
testing_debugging_claims: 'MEDIUM',
|
|
59
|
+
|
|
60
|
+
// LOW - Low threat, flagged for awareness
|
|
61
|
+
leetspeak_obfuscation: 'LOW',
|
|
62
|
+
capability_probing: 'LOW',
|
|
63
|
+
negative_instruction: 'LOW',
|
|
64
|
+
time_based_triggers: 'LOW',
|
|
65
|
+
whitespace_steganography: 'LOW'
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Classify severity for a single pattern category
|
|
70
|
+
*/
|
|
71
|
+
export function classifySeverity(patternCategory: string): Severity {
|
|
72
|
+
return SEVERITY_MAP[patternCategory] || 'LOW';
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Interface for a threat finding
|
|
77
|
+
*/
|
|
78
|
+
export interface Finding {
|
|
79
|
+
pattern_category: string;
|
|
80
|
+
severity: Severity;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Aggregate severity across multiple findings
|
|
85
|
+
* Returns the highest severity level found, or CLEAN if no findings
|
|
86
|
+
*/
|
|
87
|
+
export function aggregateSeverity(findings: Finding[]): OverallSeverity {
|
|
88
|
+
if (findings.length === 0) {
|
|
89
|
+
return 'CLEAN';
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const severities = findings.map(f => f.severity);
|
|
93
|
+
|
|
94
|
+
if (severities.includes('CRITICAL')) return 'CRITICAL';
|
|
95
|
+
if (severities.includes('HIGH')) return 'HIGH';
|
|
96
|
+
if (severities.includes('MEDIUM')) return 'MEDIUM';
|
|
97
|
+
if (severities.includes('LOW')) return 'LOW';
|
|
98
|
+
|
|
99
|
+
return 'CLEAN';
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Count findings by severity level
|
|
104
|
+
*/
|
|
105
|
+
export function countBySeverity(findings: Finding[]): Record<Severity, number> {
|
|
106
|
+
const counts: Record<Severity, number> = {
|
|
107
|
+
CRITICAL: 0,
|
|
108
|
+
HIGH: 0,
|
|
109
|
+
MEDIUM: 0,
|
|
110
|
+
LOW: 0
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
for (const finding of findings) {
|
|
114
|
+
counts[finding.severity]++;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return counts;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Get emoji for severity level (for Markdown reports)
|
|
122
|
+
*/
|
|
123
|
+
export function getSeverityEmoji(severity: Severity | OverallSeverity): string {
|
|
124
|
+
switch (severity) {
|
|
125
|
+
case 'CRITICAL': return '🔴';
|
|
126
|
+
case 'HIGH': return '🟠';
|
|
127
|
+
case 'MEDIUM': return '🟡';
|
|
128
|
+
case 'LOW': return '🟢';
|
|
129
|
+
case 'CLEAN': return '✅';
|
|
130
|
+
default: return '⚪';
|
|
131
|
+
}
|
|
132
|
+
}
|