visus-mcp 0.2.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.
Files changed (107) hide show
  1. package/.claude/settings.local.json +22 -0
  2. package/LINKEDIN-STRATEGY.md +367 -0
  3. package/README.md +491 -16
  4. package/ROADMAP.md +214 -34
  5. package/SECURITY-AUDIT-v1.md +277 -0
  6. package/STATUS.md +801 -42
  7. package/TROUBLESHOOT-AUTH-20260322-2019.md +291 -0
  8. package/TROUBLESHOOT-JEST-20260323-1357.md +139 -0
  9. package/TROUBLESHOOT-LAMBDA-20260322-1945.md +183 -0
  10. package/VISUS-CLAUDE-CODE-PROMPT.md +1 -1
  11. package/VISUS-PROJECT-PLAN.md +7 -0
  12. package/dist/browser/playwright-renderer.d.ts.map +1 -1
  13. package/dist/browser/playwright-renderer.js +7 -0
  14. package/dist/browser/playwright-renderer.js.map +1 -1
  15. package/dist/browser/reader.d.ts +31 -0
  16. package/dist/browser/reader.d.ts.map +1 -0
  17. package/dist/browser/reader.js +98 -0
  18. package/dist/browser/reader.js.map +1 -0
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +37 -5
  22. package/dist/index.js.map +1 -1
  23. package/dist/lambda-handler.d.ts +0 -6
  24. package/dist/lambda-handler.d.ts.map +1 -1
  25. package/dist/lambda-handler.js +97 -25
  26. package/dist/lambda-handler.js.map +1 -1
  27. package/dist/sanitizer/framework-mapper.d.ts +22 -0
  28. package/dist/sanitizer/framework-mapper.d.ts.map +1 -0
  29. package/dist/sanitizer/framework-mapper.js +296 -0
  30. package/dist/sanitizer/framework-mapper.js.map +1 -0
  31. package/dist/sanitizer/index.d.ts +10 -2
  32. package/dist/sanitizer/index.d.ts.map +1 -1
  33. package/dist/sanitizer/index.js +22 -6
  34. package/dist/sanitizer/index.js.map +1 -1
  35. package/dist/sanitizer/patterns.js +1 -1
  36. package/dist/sanitizer/patterns.js.map +1 -1
  37. package/dist/sanitizer/pii-allowlist.d.ts +49 -0
  38. package/dist/sanitizer/pii-allowlist.d.ts.map +1 -0
  39. package/dist/sanitizer/pii-allowlist.js +231 -0
  40. package/dist/sanitizer/pii-allowlist.js.map +1 -0
  41. package/dist/sanitizer/pii-redactor.d.ts +13 -1
  42. package/dist/sanitizer/pii-redactor.d.ts.map +1 -1
  43. package/dist/sanitizer/pii-redactor.js +26 -2
  44. package/dist/sanitizer/pii-redactor.js.map +1 -1
  45. package/dist/sanitizer/severity-classifier.d.ts +33 -0
  46. package/dist/sanitizer/severity-classifier.d.ts.map +1 -0
  47. package/dist/sanitizer/severity-classifier.js +113 -0
  48. package/dist/sanitizer/severity-classifier.js.map +1 -0
  49. package/dist/sanitizer/threat-reporter.d.ts +65 -0
  50. package/dist/sanitizer/threat-reporter.d.ts.map +1 -0
  51. package/dist/sanitizer/threat-reporter.js +160 -0
  52. package/dist/sanitizer/threat-reporter.js.map +1 -0
  53. package/dist/tools/fetch-structured.d.ts +5 -0
  54. package/dist/tools/fetch-structured.d.ts.map +1 -1
  55. package/dist/tools/fetch-structured.js +59 -8
  56. package/dist/tools/fetch-structured.js.map +1 -1
  57. package/dist/tools/fetch.d.ts +5 -0
  58. package/dist/tools/fetch.d.ts.map +1 -1
  59. package/dist/tools/fetch.js +43 -9
  60. package/dist/tools/fetch.js.map +1 -1
  61. package/dist/tools/read.d.ts +51 -0
  62. package/dist/tools/read.d.ts.map +1 -0
  63. package/dist/tools/read.js +127 -0
  64. package/dist/tools/read.js.map +1 -0
  65. package/dist/tools/search.d.ts +45 -0
  66. package/dist/tools/search.d.ts.map +1 -0
  67. package/dist/tools/search.js +220 -0
  68. package/dist/tools/search.js.map +1 -0
  69. package/dist/types.d.ts +74 -0
  70. package/dist/types.d.ts.map +1 -1
  71. package/dist/types.js.map +1 -1
  72. package/dist/utils/format-converter.d.ts +39 -0
  73. package/dist/utils/format-converter.d.ts.map +1 -0
  74. package/dist/utils/format-converter.js +191 -0
  75. package/dist/utils/format-converter.js.map +1 -0
  76. package/dist/utils/truncate.d.ts +26 -0
  77. package/dist/utils/truncate.d.ts.map +1 -0
  78. package/dist/utils/truncate.js +54 -0
  79. package/dist/utils/truncate.js.map +1 -0
  80. package/infrastructure/stack.ts +55 -6
  81. package/jest.config.js +3 -0
  82. package/package.json +9 -2
  83. package/src/browser/playwright-renderer.ts +8 -0
  84. package/src/browser/reader.ts +129 -0
  85. package/src/index.ts +49 -5
  86. package/src/lambda-handler.ts +131 -26
  87. package/src/sanitizer/framework-mapper.ts +347 -0
  88. package/src/sanitizer/index.ts +28 -6
  89. package/src/sanitizer/patterns.ts +1 -1
  90. package/src/sanitizer/pii-allowlist.ts +273 -0
  91. package/src/sanitizer/pii-redactor.ts +43 -2
  92. package/src/sanitizer/severity-classifier.ts +132 -0
  93. package/src/sanitizer/threat-reporter.ts +261 -0
  94. package/src/tools/fetch-structured.ts +63 -8
  95. package/src/tools/fetch.ts +45 -9
  96. package/src/tools/read.ts +143 -0
  97. package/src/tools/search.ts +263 -0
  98. package/src/types.ts +71 -0
  99. package/src/utils/format-converter.ts +236 -0
  100. package/src/utils/truncate.ts +64 -0
  101. package/tests/auth-smoke.test.ts +480 -0
  102. package/tests/fetch-tool.test.ts +595 -2
  103. package/tests/pii-allowlist.test.ts +282 -0
  104. package/tests/reader.test.ts +353 -0
  105. package/tests/sanitizer.test.ts +52 -0
  106. package/tests/search.test.ts +456 -0
  107. package/tests/threat-reporter.test.ts +266 -0
package/src/index.ts CHANGED
@@ -27,6 +27,8 @@ import {
27
27
 
28
28
  import { visusFetch, visusFetchToolDefinition } from './tools/fetch.js';
29
29
  import { visusFetchStructured, visusFetchStructuredToolDefinition } from './tools/fetch-structured.js';
30
+ import { visusRead, visusReadToolDefinition } from './tools/read.js';
31
+ import { visusSearch, visusSearchToolDefinition } from './tools/search.js';
30
32
  import { closeBrowser } from './browser/playwright-renderer.js';
31
33
  import { detectRuntime, logRuntimeConfig, validateRuntime } from './runtime.js';
32
34
 
@@ -52,7 +54,9 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
52
54
  return {
53
55
  tools: [
54
56
  visusFetchToolDefinition,
55
- visusFetchStructuredToolDefinition
57
+ visusFetchStructuredToolDefinition,
58
+ visusReadToolDefinition,
59
+ visusSearchToolDefinition
56
60
  ]
57
61
  };
58
62
  });
@@ -105,6 +109,46 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
105
109
  };
106
110
  }
107
111
 
112
+ case 'visus_read': {
113
+ const result = await visusRead(args as any);
114
+
115
+ if (!result.ok) {
116
+ throw new McpError(
117
+ ErrorCode.InternalError,
118
+ `visus_read failed: ${result.error.message}`
119
+ );
120
+ }
121
+
122
+ return {
123
+ content: [
124
+ {
125
+ type: 'text',
126
+ text: JSON.stringify(result.value, null, 2)
127
+ }
128
+ ]
129
+ };
130
+ }
131
+
132
+ case 'visus_search': {
133
+ const result = await visusSearch(args as any);
134
+
135
+ if (!result.ok) {
136
+ throw new McpError(
137
+ ErrorCode.InternalError,
138
+ `visus_search failed: ${result.error.message}`
139
+ );
140
+ }
141
+
142
+ return {
143
+ content: [
144
+ {
145
+ type: 'text',
146
+ text: JSON.stringify(result.value, null, 2)
147
+ }
148
+ ]
149
+ };
150
+ }
151
+
108
152
  default:
109
153
  throw new McpError(
110
154
  ErrorCode.MethodNotFound,
@@ -138,7 +182,7 @@ async function startMcpServer() {
138
182
  event: 'mcp_server_started',
139
183
  name: 'visus-mcp',
140
184
  version: '0.2.0',
141
- tools: ['visus_fetch', 'visus_fetch_structured']
185
+ tools: ['visus_fetch', 'visus_fetch_structured', 'visus_read', 'visus_search']
142
186
  }));
143
187
 
144
188
  // Graceful shutdown
@@ -188,9 +232,9 @@ async function main() {
188
232
  }
189
233
  }
190
234
 
191
- // Export Lambda handlers (for AWS deployment)
192
- // These are only used when the file is imported as a module by Lambda runtime
193
- export { handler, healthCheck } from './lambda-handler.js';
235
+ // Export Lambda handler (for AWS deployment)
236
+ // This is only used when the file is imported as a module by Lambda runtime
237
+ export { handler } from './lambda-handler.js';
194
238
 
195
239
  // Run stdio MCP server when executed directly (not in Lambda)
196
240
  if (!process.env.AWS_LAMBDA_FUNCTION_NAME) {
@@ -14,10 +14,16 @@
14
14
  */
15
15
 
16
16
  import type { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
17
+ import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
18
+ import { DynamoDBDocumentClient, PutCommand } from '@aws-sdk/lib-dynamodb';
17
19
  import { visusFetch } from './tools/fetch.js';
18
20
  import { visusFetchStructured } from './tools/fetch-structured.js';
19
21
  import { closeBrowser } from './browser/playwright-renderer.js';
20
22
 
23
+ // Initialize DynamoDB client
24
+ const ddbClient = new DynamoDBClient({});
25
+ const docClient = DynamoDBDocumentClient.from(ddbClient);
26
+
21
27
  /**
22
28
  * API request body for visus_fetch
23
29
  */
@@ -36,6 +42,63 @@ interface FetchStructuredRequest {
36
42
  timeout_ms?: number;
37
43
  }
38
44
 
45
+ /**
46
+ * Fire-and-forget audit logging to DynamoDB
47
+ *
48
+ * Logs request metadata without blocking the response.
49
+ * Errors are logged but do not affect the API response.
50
+ *
51
+ * @param userId User ID from Cognito JWT
52
+ * @param requestId AWS request ID
53
+ * @param url URL being fetched
54
+ * @param endpoint API endpoint (/fetch or /fetch-structured)
55
+ * @param patternsDetected Sanitization patterns detected
56
+ * @param piiRedacted PII types redacted
57
+ */
58
+ function logAuditEvent(
59
+ userId: string,
60
+ requestId: string,
61
+ url: string,
62
+ endpoint: string,
63
+ patternsDetected: string[],
64
+ piiRedacted: string[]
65
+ ): void {
66
+ const tableName = process.env.AUDIT_TABLE_NAME;
67
+
68
+ if (!tableName) {
69
+ console.error('AUDIT_TABLE_NAME not set - skipping audit logging');
70
+ return;
71
+ }
72
+
73
+ const now = new Date();
74
+ const ttl = Math.floor(now.getTime() / 1000) + (30 * 24 * 60 * 60); // 30 days from now
75
+
76
+ const item = {
77
+ user_id: userId,
78
+ timestamp: now.toISOString(),
79
+ request_id: requestId,
80
+ url,
81
+ endpoint,
82
+ patterns_detected: patternsDetected,
83
+ pii_redacted: piiRedacted,
84
+ ttl, // Auto-delete after 30 days
85
+ };
86
+
87
+ // Fire-and-forget: do not await
88
+ docClient.send(new PutCommand({
89
+ TableName: tableName,
90
+ Item: item,
91
+ })).catch((error: unknown) => {
92
+ // Log error but do not throw (fire-and-forget pattern)
93
+ console.error(JSON.stringify({
94
+ timestamp: now.toISOString(),
95
+ event: 'audit_logging_failed',
96
+ error: error instanceof Error ? error.message : String(error),
97
+ request_id: requestId,
98
+ }));
99
+ });
100
+ }
101
+
39
102
  /**
40
103
  * Lambda handler for Visus API
41
104
  *
@@ -65,10 +128,14 @@ export async function handler(
65
128
  }));
66
129
 
67
130
  try {
68
- // CORS headers for all responses
131
+ // CORS headers for all responses (environment-variable-driven allowlist)
132
+ const allowedOrigins = (process.env.ALLOWED_ORIGINS || '*').split(',');
133
+ const origin = event.headers.origin || event.headers.Origin || '';
134
+ const allowOrigin = allowedOrigins.includes(origin) ? origin : allowedOrigins[0] || '*';
135
+
69
136
  const corsHeaders = {
70
- 'Access-Control-Allow-Origin': '*', // Phase 2: Open. Phase 3: Restrict to Lateos domains
71
- 'Access-Control-Allow-Methods': 'POST, OPTIONS',
137
+ 'Access-Control-Allow-Origin': allowOrigin,
138
+ 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
72
139
  'Access-Control-Allow-Headers': 'Content-Type, Authorization',
73
140
  'Content-Type': 'application/json',
74
141
  };
@@ -82,7 +149,22 @@ export async function handler(
82
149
  };
83
150
  }
84
151
 
85
- // Only allow POST requests
152
+ // Health check endpoint (no auth required, allows GET and POST)
153
+ // SECURITY FIX (FINDING 2): Moved before POST-only validation to support standard GET health checks
154
+ if (event.path === '/health' || event.path === '/dev/health' || event.path === '/prod/health') {
155
+ return {
156
+ statusCode: 200,
157
+ headers: corsHeaders,
158
+ body: JSON.stringify({
159
+ status: 'healthy',
160
+ service: 'visus-mcp',
161
+ version: '0.3.1',
162
+ timestamp: new Date().toISOString(),
163
+ }),
164
+ };
165
+ }
166
+
167
+ // Only allow POST requests for protected endpoints
86
168
  if (event.httpMethod !== 'POST') {
87
169
  return {
88
170
  statusCode: 405,
@@ -103,8 +185,31 @@ export async function handler(
103
185
  };
104
186
  }
105
187
 
188
+ // SECURITY FIX (FINDING 1): Application-level authentication enforcement
189
+ // Extract user ID from Cognito authorizer
190
+ const userId = event.requestContext.authorizer?.claims?.sub;
191
+
192
+ // Require authentication for all protected endpoints (not already handled above)
193
+ if (!userId) {
194
+ console.error(JSON.stringify({
195
+ timestamp: new Date().toISOString(),
196
+ event: 'auth_required',
197
+ request_id: requestId,
198
+ path: event.path,
199
+ reason: 'Missing Cognito authorizer context - Lambda must be invoked via API Gateway',
200
+ }));
201
+
202
+ return {
203
+ statusCode: 401,
204
+ headers: corsHeaders,
205
+ body: JSON.stringify({
206
+ error: 'Unauthorized: Authentication required. This Lambda must be invoked via API Gateway with Cognito authorizer.',
207
+ }),
208
+ };
209
+ }
210
+
106
211
  // Route based on path
107
- if (event.path === '/fetch' || event.path === '/prod/fetch') {
212
+ if (event.path === '/fetch' || event.path === '/dev/fetch' || event.path === '/prod/fetch') {
108
213
  const fetchReq = body as FetchRequest;
109
214
 
110
215
  // Validate request
@@ -127,6 +232,16 @@ export async function handler(
127
232
  };
128
233
  }
129
234
 
235
+ // Fire-and-forget audit logging
236
+ logAuditEvent(
237
+ userId,
238
+ requestId,
239
+ fetchReq.url,
240
+ '/fetch',
241
+ result.value.sanitization.patterns_detected,
242
+ result.value.sanitization.pii_types_redacted
243
+ );
244
+
130
245
  return {
131
246
  statusCode: 200,
132
247
  headers: corsHeaders,
@@ -134,7 +249,7 @@ export async function handler(
134
249
  };
135
250
  }
136
251
 
137
- if (event.path === '/fetch-structured' || event.path === '/prod/fetch-structured') {
252
+ if (event.path === '/fetch-structured' || event.path === '/dev/fetch-structured' || event.path === '/prod/fetch-structured') {
138
253
  const fetchReq = body as FetchStructuredRequest;
139
254
 
140
255
  // Validate request
@@ -165,6 +280,16 @@ export async function handler(
165
280
  };
166
281
  }
167
282
 
283
+ // Fire-and-forget audit logging
284
+ logAuditEvent(
285
+ userId,
286
+ requestId,
287
+ fetchReq.url,
288
+ '/fetch-structured',
289
+ result.value.sanitization.patterns_detected,
290
+ result.value.sanitization.pii_types_redacted
291
+ );
292
+
168
293
  return {
169
294
  statusCode: 200,
170
295
  headers: corsHeaders,
@@ -203,23 +328,3 @@ export async function handler(
203
328
  await closeBrowser();
204
329
  }
205
330
  }
206
-
207
- /**
208
- * Health check handler
209
- *
210
- * @returns API Gateway response
211
- */
212
- export async function healthCheck(): Promise<APIGatewayProxyResult> {
213
- return {
214
- statusCode: 200,
215
- headers: {
216
- 'Content-Type': 'application/json',
217
- },
218
- body: JSON.stringify({
219
- status: 'healthy',
220
- service: 'visus-mcp',
221
- version: '0.2.0',
222
- timestamp: new Date().toISOString(),
223
- }),
224
- };
225
- }
@@ -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
+ }