llm-trust-guard 4.0.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 (115) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +318 -0
  3. package/dist/guards/agent-communication-guard.d.ts +169 -0
  4. package/dist/guards/agent-communication-guard.d.ts.map +1 -0
  5. package/dist/guards/agent-communication-guard.js +468 -0
  6. package/dist/guards/agent-communication-guard.js.map +1 -0
  7. package/dist/guards/autonomy-escalation-guard.d.ts +137 -0
  8. package/dist/guards/autonomy-escalation-guard.d.ts.map +1 -0
  9. package/dist/guards/autonomy-escalation-guard.js +470 -0
  10. package/dist/guards/autonomy-escalation-guard.js.map +1 -0
  11. package/dist/guards/circuit-breaker.d.ts +142 -0
  12. package/dist/guards/circuit-breaker.d.ts.map +1 -0
  13. package/dist/guards/circuit-breaker.js +347 -0
  14. package/dist/guards/circuit-breaker.js.map +1 -0
  15. package/dist/guards/code-execution-guard.d.ts +114 -0
  16. package/dist/guards/code-execution-guard.d.ts.map +1 -0
  17. package/dist/guards/code-execution-guard.js +467 -0
  18. package/dist/guards/code-execution-guard.js.map +1 -0
  19. package/dist/guards/conversation-guard.d.ts +73 -0
  20. package/dist/guards/conversation-guard.d.ts.map +1 -0
  21. package/dist/guards/conversation-guard.js +281 -0
  22. package/dist/guards/conversation-guard.js.map +1 -0
  23. package/dist/guards/drift-detector.d.ts +182 -0
  24. package/dist/guards/drift-detector.d.ts.map +1 -0
  25. package/dist/guards/drift-detector.js +480 -0
  26. package/dist/guards/drift-detector.js.map +1 -0
  27. package/dist/guards/encoding-detector.d.ts +76 -0
  28. package/dist/guards/encoding-detector.d.ts.map +1 -0
  29. package/dist/guards/encoding-detector.js +698 -0
  30. package/dist/guards/encoding-detector.js.map +1 -0
  31. package/dist/guards/execution-monitor.d.ts +73 -0
  32. package/dist/guards/execution-monitor.d.ts.map +1 -0
  33. package/dist/guards/execution-monitor.js +205 -0
  34. package/dist/guards/execution-monitor.js.map +1 -0
  35. package/dist/guards/input-sanitizer.d.ts +87 -0
  36. package/dist/guards/input-sanitizer.d.ts.map +1 -0
  37. package/dist/guards/input-sanitizer.js +301 -0
  38. package/dist/guards/input-sanitizer.js.map +1 -0
  39. package/dist/guards/mcp-security-guard.d.ts +204 -0
  40. package/dist/guards/mcp-security-guard.d.ts.map +1 -0
  41. package/dist/guards/mcp-security-guard.js +618 -0
  42. package/dist/guards/mcp-security-guard.js.map +1 -0
  43. package/dist/guards/memory-guard.d.ts +124 -0
  44. package/dist/guards/memory-guard.d.ts.map +1 -0
  45. package/dist/guards/memory-guard.js +476 -0
  46. package/dist/guards/memory-guard.js.map +1 -0
  47. package/dist/guards/multimodal-guard.d.ts +93 -0
  48. package/dist/guards/multimodal-guard.d.ts.map +1 -0
  49. package/dist/guards/multimodal-guard.js +507 -0
  50. package/dist/guards/multimodal-guard.js.map +1 -0
  51. package/dist/guards/output-filter.d.ts +76 -0
  52. package/dist/guards/output-filter.d.ts.map +1 -0
  53. package/dist/guards/output-filter.js +289 -0
  54. package/dist/guards/output-filter.js.map +1 -0
  55. package/dist/guards/policy-gate.d.ts +57 -0
  56. package/dist/guards/policy-gate.d.ts.map +1 -0
  57. package/dist/guards/policy-gate.js +182 -0
  58. package/dist/guards/policy-gate.js.map +1 -0
  59. package/dist/guards/prompt-leakage-guard.d.ts +110 -0
  60. package/dist/guards/prompt-leakage-guard.d.ts.map +1 -0
  61. package/dist/guards/prompt-leakage-guard.js +529 -0
  62. package/dist/guards/prompt-leakage-guard.js.map +1 -0
  63. package/dist/guards/rag-guard.d.ts +188 -0
  64. package/dist/guards/rag-guard.d.ts.map +1 -0
  65. package/dist/guards/rag-guard.js +769 -0
  66. package/dist/guards/rag-guard.js.map +1 -0
  67. package/dist/guards/schema-validator.d.ts +35 -0
  68. package/dist/guards/schema-validator.d.ts.map +1 -0
  69. package/dist/guards/schema-validator.js +316 -0
  70. package/dist/guards/schema-validator.js.map +1 -0
  71. package/dist/guards/state-persistence-guard.d.ts +153 -0
  72. package/dist/guards/state-persistence-guard.d.ts.map +1 -0
  73. package/dist/guards/state-persistence-guard.js +484 -0
  74. package/dist/guards/state-persistence-guard.js.map +1 -0
  75. package/dist/guards/tenant-boundary.d.ts +67 -0
  76. package/dist/guards/tenant-boundary.d.ts.map +1 -0
  77. package/dist/guards/tenant-boundary.js +187 -0
  78. package/dist/guards/tenant-boundary.js.map +1 -0
  79. package/dist/guards/tool-chain-validator.d.ts +102 -0
  80. package/dist/guards/tool-chain-validator.d.ts.map +1 -0
  81. package/dist/guards/tool-chain-validator.js +480 -0
  82. package/dist/guards/tool-chain-validator.js.map +1 -0
  83. package/dist/guards/tool-registry.d.ts +45 -0
  84. package/dist/guards/tool-registry.d.ts.map +1 -0
  85. package/dist/guards/tool-registry.js +155 -0
  86. package/dist/guards/tool-registry.js.map +1 -0
  87. package/dist/guards/trust-exploitation-guard.d.ts +134 -0
  88. package/dist/guards/trust-exploitation-guard.d.ts.map +1 -0
  89. package/dist/guards/trust-exploitation-guard.js +354 -0
  90. package/dist/guards/trust-exploitation-guard.js.map +1 -0
  91. package/dist/index.d.ts +133 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +430 -0
  94. package/dist/index.js.map +1 -0
  95. package/dist/integrations/express.d.ts +119 -0
  96. package/dist/integrations/express.d.ts.map +1 -0
  97. package/dist/integrations/express.js +244 -0
  98. package/dist/integrations/express.js.map +1 -0
  99. package/dist/integrations/index.d.ts +9 -0
  100. package/dist/integrations/index.d.ts.map +1 -0
  101. package/dist/integrations/index.js +26 -0
  102. package/dist/integrations/index.js.map +1 -0
  103. package/dist/integrations/langchain.d.ts +165 -0
  104. package/dist/integrations/langchain.d.ts.map +1 -0
  105. package/dist/integrations/langchain.js +308 -0
  106. package/dist/integrations/langchain.js.map +1 -0
  107. package/dist/integrations/openai.d.ts +205 -0
  108. package/dist/integrations/openai.d.ts.map +1 -0
  109. package/dist/integrations/openai.js +380 -0
  110. package/dist/integrations/openai.js.map +1 -0
  111. package/dist/types/index.d.ts +245 -0
  112. package/dist/types/index.d.ts.map +1 -0
  113. package/dist/types/index.js +6 -0
  114. package/dist/types/index.js.map +1 -0
  115. package/package.json +64 -0
@@ -0,0 +1,93 @@
1
+ /**
2
+ * MultiModalGuard (L8)
3
+ *
4
+ * Detects hidden instructions and malicious content in multi-modal inputs
5
+ * (images, audio, documents, base64 payloads).
6
+ *
7
+ * Threat Model:
8
+ * - ASI01: Agent Goal Hijack via manipulated media
9
+ * - Multi-Modal Injection: Hidden text in images, audio with embedded instructions
10
+ *
11
+ * Detection Capabilities:
12
+ * - Image metadata (EXIF) injection
13
+ * - Steganographic patterns
14
+ * - Hidden text detection (white-on-white, etc.)
15
+ * - Base64 embedded payloads
16
+ * - Document macro/script detection
17
+ * - Audio transcript injection markers
18
+ */
19
+ export interface MultiModalGuardConfig {
20
+ /** Enable EXIF/metadata scanning */
21
+ scanMetadata?: boolean;
22
+ /** Enable base64 payload detection */
23
+ detectBase64Payloads?: boolean;
24
+ /** Enable steganography detection heuristics */
25
+ detectSteganography?: boolean;
26
+ /** Maximum allowed metadata size in bytes */
27
+ maxMetadataSize?: number;
28
+ /** Suspicious patterns to detect in extracted text */
29
+ customPatterns?: RegExp[];
30
+ /** Allowed MIME types */
31
+ allowedMimeTypes?: string[];
32
+ /** Block all multi-modal content (strict mode) */
33
+ strictMode?: boolean;
34
+ }
35
+ export interface MultiModalContent {
36
+ /** Content type: image, audio, document, base64 */
37
+ type: "image" | "audio" | "document" | "base64" | "url";
38
+ /** Raw content or base64 string */
39
+ content?: string;
40
+ /** MIME type if known */
41
+ mimeType?: string;
42
+ /** URL if remote content */
43
+ url?: string;
44
+ /** Filename if provided */
45
+ filename?: string;
46
+ /** Extracted metadata */
47
+ metadata?: Record<string, any>;
48
+ /** Any extracted text (OCR, transcripts, etc.) */
49
+ extractedText?: string;
50
+ }
51
+ export interface MultiModalGuardResult {
52
+ allowed: boolean;
53
+ reason: string;
54
+ violations: string[];
55
+ request_id: string;
56
+ content_analysis: {
57
+ type: string;
58
+ threats_detected: string[];
59
+ metadata_suspicious: boolean;
60
+ hidden_content_detected: boolean;
61
+ injection_patterns_found: string[];
62
+ risk_score: number;
63
+ };
64
+ recommendations: string[];
65
+ }
66
+ export declare class MultiModalGuard {
67
+ private config;
68
+ private readonly INJECTION_PATTERNS;
69
+ private readonly SUSPICIOUS_METADATA_FIELDS;
70
+ private readonly DANGEROUS_MIME_TYPES;
71
+ private readonly STEGO_MARKERS;
72
+ constructor(config?: MultiModalGuardConfig);
73
+ /**
74
+ * Analyze multi-modal content for hidden instructions or malicious payloads
75
+ */
76
+ check(content: MultiModalContent, requestId?: string): MultiModalGuardResult;
77
+ /**
78
+ * Batch check multiple content items
79
+ */
80
+ checkBatch(contents: MultiModalContent[], requestId?: string): MultiModalGuardResult;
81
+ /**
82
+ * Extract and analyze image metadata (EXIF simulation)
83
+ * In production, use a proper EXIF parser
84
+ */
85
+ parseImageMetadata(base64Image: string): Record<string, any>;
86
+ private scanMetadata;
87
+ private scanText;
88
+ private detectBase64Payloads;
89
+ private detectSteganography;
90
+ private checkUrl;
91
+ private generateRecommendations;
92
+ }
93
+ //# sourceMappingURL=multimodal-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multimodal-guard.d.ts","sourceRoot":"","sources":["../../src/guards/multimodal-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,qBAAqB;IACpC,oCAAoC;IACpC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,sCAAsC;IACtC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,gDAAgD;IAChD,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,6CAA6C;IAC7C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sDAAsD;IACtD,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,yBAAyB;IACzB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,kDAAkD;IAClD,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,mDAAmD;IACnD,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,KAAK,CAAC;IACxD,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,kDAAkD;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,gBAAgB,EAAE,MAAM,EAAE,CAAC;QAC3B,mBAAmB,EAAE,OAAO,CAAC;QAC7B,uBAAuB,EAAE,OAAO,CAAC;QACjC,wBAAwB,EAAE,MAAM,EAAE,CAAC;QACnC,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAkC;IAGhD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAUjC;IAGF,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAazC;IAGF,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CASnC;IAGF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAK5B;gBAEU,MAAM,GAAE,qBAA0B;IAsB9C;;OAEG;IACH,KAAK,CACH,OAAO,EAAE,iBAAiB,EAC1B,SAAS,CAAC,EAAE,MAAM,GACjB,qBAAqB;IA8KxB;;OAEG;IACH,UAAU,CACR,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,SAAS,CAAC,EAAE,MAAM,GACjB,qBAAqB;IAwCxB;;;OAGG;IACH,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAgC5D,OAAO,CAAC,YAAY;IAoDpB,OAAO,CAAC,QAAQ;IA0ChB,OAAO,CAAC,oBAAoB;IA6B5B,OAAO,CAAC,mBAAmB;IA6B3B,OAAO,CAAC,QAAQ;IAsDhB,OAAO,CAAC,uBAAuB;CAyBhC"}
@@ -0,0 +1,507 @@
1
+ "use strict";
2
+ /**
3
+ * MultiModalGuard (L8)
4
+ *
5
+ * Detects hidden instructions and malicious content in multi-modal inputs
6
+ * (images, audio, documents, base64 payloads).
7
+ *
8
+ * Threat Model:
9
+ * - ASI01: Agent Goal Hijack via manipulated media
10
+ * - Multi-Modal Injection: Hidden text in images, audio with embedded instructions
11
+ *
12
+ * Detection Capabilities:
13
+ * - Image metadata (EXIF) injection
14
+ * - Steganographic patterns
15
+ * - Hidden text detection (white-on-white, etc.)
16
+ * - Base64 embedded payloads
17
+ * - Document macro/script detection
18
+ * - Audio transcript injection markers
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.MultiModalGuard = void 0;
22
+ class MultiModalGuard {
23
+ constructor(config = {}) {
24
+ // Suspicious patterns in metadata or extracted text
25
+ this.INJECTION_PATTERNS = [
26
+ { name: "ignore_instructions", pattern: /ignore\s+(all\s+)?(previous|prior|above)\s+(instructions|rules|guidelines)/i },
27
+ { name: "system_override", pattern: /\[SYSTEM\]|\[ADMIN\]|\[OVERRIDE\]|<\s*system\s*>|<\s*admin\s*>/i },
28
+ { name: "role_switch", pattern: /you\s+are\s+(now|actually)\s+(a|an|the)|switch\s+to\s+(\w+)\s+mode/i },
29
+ { name: "hidden_prompt", pattern: /HIDDEN_PROMPT|SECRET_INSTRUCTION|INVISIBLE_COMMAND/i },
30
+ { name: "jailbreak_markers", pattern: /DAN\s*mode|developer\s*mode|unrestricted\s*mode|bypass\s*safety/i },
31
+ { name: "base64_instruction", pattern: /execute\s*:\s*[A-Za-z0-9+/=]{20,}/i },
32
+ { name: "command_injection", pattern: /;\s*(rm|del|wget|curl|eval|exec)\s/i },
33
+ { name: "exfiltration_markers", pattern: /send\s+(to|this|data)\s+(to\s+)?https?:\/\//i },
34
+ { name: "invisible_unicode", pattern: /[\u200B-\u200D\uFEFF\u2060-\u206F]/g },
35
+ ];
36
+ // Suspicious EXIF fields that could contain injection
37
+ this.SUSPICIOUS_METADATA_FIELDS = [
38
+ "ImageDescription",
39
+ "UserComment",
40
+ "XPComment",
41
+ "XPKeywords",
42
+ "XPSubject",
43
+ "XPTitle",
44
+ "Artist",
45
+ "Copyright",
46
+ "Software",
47
+ "HostComputer",
48
+ "DocumentName",
49
+ "PageName",
50
+ ];
51
+ // Known dangerous MIME types
52
+ this.DANGEROUS_MIME_TYPES = [
53
+ "application/x-msdownload",
54
+ "application/x-msdos-program",
55
+ "application/x-sh",
56
+ "application/x-shellscript",
57
+ "application/javascript",
58
+ "text/javascript",
59
+ "application/x-python",
60
+ "application/vnd.ms-office",
61
+ ];
62
+ // Steganography detection patterns (simplified heuristics)
63
+ this.STEGO_MARKERS = [
64
+ /^[\x00-\x08\x0B\x0C\x0E-\x1F]{4,}/, // Unusual control characters
65
+ /PK\x03\x04/, // ZIP header (could be embedded)
66
+ /%PDF-/, // Embedded PDF
67
+ /\x89PNG.*IEND.*[A-Za-z]{10,}/, // Data after PNG end
68
+ ];
69
+ this.config = {
70
+ scanMetadata: config.scanMetadata ?? true,
71
+ detectBase64Payloads: config.detectBase64Payloads ?? true,
72
+ detectSteganography: config.detectSteganography ?? true,
73
+ maxMetadataSize: config.maxMetadataSize ?? 10000, // 10KB
74
+ customPatterns: config.customPatterns ?? [],
75
+ allowedMimeTypes: config.allowedMimeTypes ?? [
76
+ "image/jpeg",
77
+ "image/png",
78
+ "image/gif",
79
+ "image/webp",
80
+ "audio/mpeg",
81
+ "audio/wav",
82
+ "audio/ogg",
83
+ "application/pdf",
84
+ "text/plain",
85
+ ],
86
+ strictMode: config.strictMode ?? false,
87
+ };
88
+ }
89
+ /**
90
+ * Analyze multi-modal content for hidden instructions or malicious payloads
91
+ */
92
+ check(content, requestId) {
93
+ const reqId = requestId || `mm-${Date.now()}`;
94
+ const violations = [];
95
+ const threatsDetected = [];
96
+ const injectionPatternsFound = [];
97
+ let riskScore = 0;
98
+ let metadataSuspicious = false;
99
+ let hiddenContentDetected = false;
100
+ // Strict mode blocks all multi-modal content
101
+ if (this.config.strictMode) {
102
+ return {
103
+ allowed: false,
104
+ reason: "Multi-modal content blocked in strict mode",
105
+ violations: ["strict_mode_block"],
106
+ request_id: reqId,
107
+ content_analysis: {
108
+ type: content.type,
109
+ threats_detected: ["strict_mode"],
110
+ metadata_suspicious: false,
111
+ hidden_content_detected: false,
112
+ injection_patterns_found: [],
113
+ risk_score: 100,
114
+ },
115
+ recommendations: ["Disable strict mode to allow multi-modal content"],
116
+ };
117
+ }
118
+ // Check MIME type
119
+ if (content.mimeType) {
120
+ if (this.DANGEROUS_MIME_TYPES.includes(content.mimeType)) {
121
+ violations.push("dangerous_mime_type");
122
+ threatsDetected.push(`Dangerous MIME type: ${content.mimeType}`);
123
+ riskScore += 50;
124
+ }
125
+ if (!this.config.allowedMimeTypes.includes(content.mimeType)) {
126
+ violations.push("disallowed_mime_type");
127
+ threatsDetected.push(`Disallowed MIME type: ${content.mimeType}`);
128
+ riskScore += 30;
129
+ }
130
+ }
131
+ // Check for suspicious filename
132
+ if (content.filename) {
133
+ const dangerousExtensions = [".exe", ".sh", ".bat", ".cmd", ".ps1", ".vbs", ".js"];
134
+ const ext = content.filename.toLowerCase().slice(content.filename.lastIndexOf("."));
135
+ if (dangerousExtensions.includes(ext)) {
136
+ violations.push("dangerous_file_extension");
137
+ threatsDetected.push(`Dangerous file extension: ${ext}`);
138
+ riskScore += 40;
139
+ }
140
+ // Double extension attack
141
+ if (/\.(jpg|png|gif|pdf)\.(exe|sh|bat|js)$/i.test(content.filename)) {
142
+ violations.push("double_extension_attack");
143
+ threatsDetected.push("Double extension attack detected");
144
+ riskScore += 60;
145
+ }
146
+ }
147
+ // Scan metadata for injections
148
+ if (this.config.scanMetadata && content.metadata) {
149
+ const metadataResult = this.scanMetadata(content.metadata);
150
+ if (metadataResult.suspicious) {
151
+ metadataSuspicious = true;
152
+ violations.push(...metadataResult.violations);
153
+ injectionPatternsFound.push(...metadataResult.patterns);
154
+ riskScore += metadataResult.riskContribution;
155
+ }
156
+ // Check metadata size
157
+ const metadataSize = JSON.stringify(content.metadata).length;
158
+ if (metadataSize > this.config.maxMetadataSize) {
159
+ violations.push("oversized_metadata");
160
+ threatsDetected.push(`Metadata size ${metadataSize} exceeds limit ${this.config.maxMetadataSize}`);
161
+ riskScore += 20;
162
+ }
163
+ }
164
+ // Scan extracted text (OCR, transcripts) for injections
165
+ if (content.extractedText) {
166
+ const textResult = this.scanText(content.extractedText);
167
+ if (textResult.injectionFound) {
168
+ hiddenContentDetected = true;
169
+ violations.push(...textResult.violations);
170
+ injectionPatternsFound.push(...textResult.patterns);
171
+ riskScore += textResult.riskContribution;
172
+ }
173
+ }
174
+ // Detect base64 payloads in content
175
+ if (this.config.detectBase64Payloads && content.content) {
176
+ const base64Result = this.detectBase64Payloads(content.content);
177
+ if (base64Result.found) {
178
+ violations.push("embedded_base64_payload");
179
+ threatsDetected.push("Embedded base64 payload detected");
180
+ riskScore += 30;
181
+ // Decode and scan the payload
182
+ for (const payload of base64Result.payloads) {
183
+ try {
184
+ const decoded = Buffer.from(payload, "base64").toString("utf-8");
185
+ const decodedScan = this.scanText(decoded);
186
+ if (decodedScan.injectionFound) {
187
+ hiddenContentDetected = true;
188
+ violations.push("base64_injection_payload");
189
+ injectionPatternsFound.push(...decodedScan.patterns);
190
+ riskScore += 40;
191
+ }
192
+ }
193
+ catch {
194
+ // Invalid base64, skip
195
+ }
196
+ }
197
+ }
198
+ }
199
+ // Steganography detection heuristics
200
+ if (this.config.detectSteganography && content.content) {
201
+ const stegoResult = this.detectSteganography(content.content);
202
+ if (stegoResult.detected) {
203
+ violations.push("potential_steganography");
204
+ threatsDetected.push("Potential steganography detected");
205
+ hiddenContentDetected = true;
206
+ riskScore += 25;
207
+ }
208
+ }
209
+ // URL safety check
210
+ if (content.type === "url" && content.url) {
211
+ const urlResult = this.checkUrl(content.url);
212
+ if (!urlResult.safe) {
213
+ violations.push(...urlResult.violations);
214
+ threatsDetected.push(...urlResult.threats);
215
+ riskScore += urlResult.riskContribution;
216
+ }
217
+ }
218
+ // Apply custom patterns
219
+ const allText = [
220
+ content.extractedText || "",
221
+ JSON.stringify(content.metadata || {}),
222
+ ].join(" ");
223
+ for (const pattern of this.config.customPatterns) {
224
+ if (pattern.test(allText)) {
225
+ violations.push("custom_pattern_match");
226
+ injectionPatternsFound.push(`Custom: ${pattern.source.substring(0, 30)}`);
227
+ riskScore += 20;
228
+ }
229
+ }
230
+ // Calculate final decision
231
+ const blocked = riskScore >= 50 || violations.length > 0;
232
+ return {
233
+ allowed: !blocked,
234
+ reason: blocked
235
+ ? `Multi-modal content blocked: ${violations.slice(0, 3).join(", ")}`
236
+ : "Multi-modal content passed security checks",
237
+ violations,
238
+ request_id: reqId,
239
+ content_analysis: {
240
+ type: content.type,
241
+ threats_detected: threatsDetected,
242
+ metadata_suspicious: metadataSuspicious,
243
+ hidden_content_detected: hiddenContentDetected,
244
+ injection_patterns_found: injectionPatternsFound,
245
+ risk_score: Math.min(100, riskScore),
246
+ },
247
+ recommendations: this.generateRecommendations(violations),
248
+ };
249
+ }
250
+ /**
251
+ * Batch check multiple content items
252
+ */
253
+ checkBatch(contents, requestId) {
254
+ const reqId = requestId || `mm-batch-${Date.now()}`;
255
+ const allViolations = [];
256
+ const allThreats = [];
257
+ const allPatterns = [];
258
+ let totalRiskScore = 0;
259
+ let anyMetadataSuspicious = false;
260
+ let anyHiddenContent = false;
261
+ for (const content of contents) {
262
+ const result = this.check(content, reqId);
263
+ allViolations.push(...result.violations);
264
+ allThreats.push(...result.content_analysis.threats_detected);
265
+ allPatterns.push(...result.content_analysis.injection_patterns_found);
266
+ totalRiskScore = Math.max(totalRiskScore, result.content_analysis.risk_score);
267
+ anyMetadataSuspicious = anyMetadataSuspicious || result.content_analysis.metadata_suspicious;
268
+ anyHiddenContent = anyHiddenContent || result.content_analysis.hidden_content_detected;
269
+ }
270
+ const blocked = totalRiskScore >= 50 || allViolations.length > 0;
271
+ return {
272
+ allowed: !blocked,
273
+ reason: blocked
274
+ ? `Batch blocked: ${[...new Set(allViolations)].slice(0, 3).join(", ")}`
275
+ : "All multi-modal content passed security checks",
276
+ violations: [...new Set(allViolations)],
277
+ request_id: reqId,
278
+ content_analysis: {
279
+ type: `batch(${contents.length})`,
280
+ threats_detected: [...new Set(allThreats)],
281
+ metadata_suspicious: anyMetadataSuspicious,
282
+ hidden_content_detected: anyHiddenContent,
283
+ injection_patterns_found: [...new Set(allPatterns)],
284
+ risk_score: totalRiskScore,
285
+ },
286
+ recommendations: this.generateRecommendations([...new Set(allViolations)]),
287
+ };
288
+ }
289
+ /**
290
+ * Extract and analyze image metadata (EXIF simulation)
291
+ * In production, use a proper EXIF parser
292
+ */
293
+ parseImageMetadata(base64Image) {
294
+ const metadata = {};
295
+ try {
296
+ // Look for EXIF markers in the base64 content
297
+ // This is a simplified simulation - real implementation would use exif-parser
298
+ const decoded = Buffer.from(base64Image, "base64");
299
+ const content = decoded.toString("latin1");
300
+ // Look for common EXIF text patterns
301
+ const textMatches = content.match(/[\x20-\x7E]{10,}/g) || [];
302
+ for (const match of textMatches.slice(0, 20)) {
303
+ if (match.includes("=") || match.includes(":")) {
304
+ const [key, ...valueParts] = match.split(/[=:]/);
305
+ if (key && valueParts.length > 0) {
306
+ metadata[key.trim()] = valueParts.join(":").trim();
307
+ }
308
+ }
309
+ }
310
+ // Look for XML metadata (XMP)
311
+ const xmpMatch = content.match(/<x:xmpmeta[\s\S]*?<\/x:xmpmeta>/i);
312
+ if (xmpMatch) {
313
+ metadata._xmp = xmpMatch[0].substring(0, 500);
314
+ }
315
+ }
316
+ catch {
317
+ // Ignore parsing errors
318
+ }
319
+ return metadata;
320
+ }
321
+ scanMetadata(metadata) {
322
+ const violations = [];
323
+ const patterns = [];
324
+ let riskContribution = 0;
325
+ const checkValue = (key, value, path = "") => {
326
+ const currentPath = path ? `${path}.${key}` : key;
327
+ if (typeof value === "string") {
328
+ // Check suspicious fields
329
+ if (this.SUSPICIOUS_METADATA_FIELDS.includes(key)) {
330
+ for (const { name, pattern } of this.INJECTION_PATTERNS) {
331
+ if (pattern.test(value)) {
332
+ violations.push(`metadata_injection_${name}`);
333
+ patterns.push(`${name} in ${currentPath}`);
334
+ riskContribution += 30;
335
+ }
336
+ }
337
+ }
338
+ // Check all fields for obvious injection
339
+ for (const { name, pattern } of this.INJECTION_PATTERNS) {
340
+ if (pattern.test(value) && value.length > 20) {
341
+ violations.push(`metadata_${name}`);
342
+ patterns.push(`${name} in ${currentPath}`);
343
+ riskContribution += 20;
344
+ }
345
+ }
346
+ }
347
+ else if (typeof value === "object" && value !== null) {
348
+ for (const [k, v] of Object.entries(value)) {
349
+ checkValue(k, v, currentPath);
350
+ }
351
+ }
352
+ };
353
+ for (const [key, value] of Object.entries(metadata)) {
354
+ checkValue(key, value);
355
+ }
356
+ return {
357
+ suspicious: violations.length > 0,
358
+ violations: [...new Set(violations)],
359
+ patterns: [...new Set(patterns)],
360
+ riskContribution: Math.min(60, riskContribution),
361
+ };
362
+ }
363
+ scanText(text) {
364
+ const violations = [];
365
+ const patterns = [];
366
+ let riskContribution = 0;
367
+ for (const { name, pattern } of this.INJECTION_PATTERNS) {
368
+ if (pattern.test(text)) {
369
+ violations.push(`text_injection_${name}`);
370
+ patterns.push(name);
371
+ riskContribution += 25;
372
+ }
373
+ }
374
+ // Check for invisible unicode characters (used to hide instructions)
375
+ const invisibleCount = (text.match(/[\u200B-\u200D\uFEFF\u2060-\u206F]/g) || []).length;
376
+ if (invisibleCount > 5) {
377
+ violations.push("excessive_invisible_characters");
378
+ patterns.push(`invisible_unicode(${invisibleCount})`);
379
+ riskContribution += 20;
380
+ }
381
+ // Check for homoglyph attacks
382
+ const homoglyphPattern = /[\u0430-\u044F\u0410-\u042F]/; // Cyrillic that looks like Latin
383
+ if (homoglyphPattern.test(text) && /[a-zA-Z]/.test(text)) {
384
+ violations.push("potential_homoglyph_attack");
385
+ patterns.push("mixed_scripts");
386
+ riskContribution += 15;
387
+ }
388
+ return {
389
+ injectionFound: violations.length > 0,
390
+ violations,
391
+ patterns,
392
+ riskContribution: Math.min(60, riskContribution),
393
+ };
394
+ }
395
+ detectBase64Payloads(content) {
396
+ // Look for base64 patterns that might be hidden payloads
397
+ const base64Pattern = /(?:^|[^A-Za-z0-9+/])([A-Za-z0-9+/]{40,}={0,2})(?:[^A-Za-z0-9+/]|$)/g;
398
+ const payloads = [];
399
+ let match;
400
+ while ((match = base64Pattern.exec(content)) !== null) {
401
+ // Verify it's valid base64
402
+ try {
403
+ const decoded = Buffer.from(match[1], "base64");
404
+ // Check if decoded content looks like text with instructions
405
+ const text = decoded.toString("utf-8");
406
+ if (/[a-zA-Z\s]{10,}/.test(text)) {
407
+ payloads.push(match[1]);
408
+ }
409
+ }
410
+ catch {
411
+ // Not valid base64
412
+ }
413
+ }
414
+ return {
415
+ found: payloads.length > 0,
416
+ payloads,
417
+ };
418
+ }
419
+ detectSteganography(content) {
420
+ const markers = [];
421
+ for (const marker of this.STEGO_MARKERS) {
422
+ if (marker.test(content)) {
423
+ markers.push(marker.source.substring(0, 20));
424
+ }
425
+ }
426
+ // Entropy analysis (simplified)
427
+ // High entropy after expected end markers suggests hidden data
428
+ const entropyThreshold = 0.9;
429
+ const sample = content.slice(-1000);
430
+ const uniqueChars = new Set(sample).size;
431
+ const entropy = uniqueChars / sample.length;
432
+ if (entropy > entropyThreshold) {
433
+ markers.push("high_entropy_tail");
434
+ }
435
+ return {
436
+ detected: markers.length > 0,
437
+ markers,
438
+ };
439
+ }
440
+ checkUrl(url) {
441
+ const violations = [];
442
+ const threats = [];
443
+ let riskContribution = 0;
444
+ try {
445
+ const parsed = new URL(url);
446
+ // Check for suspicious protocols
447
+ if (!["http:", "https:"].includes(parsed.protocol)) {
448
+ violations.push("suspicious_protocol");
449
+ threats.push(`Suspicious protocol: ${parsed.protocol}`);
450
+ riskContribution += 40;
451
+ }
452
+ // Check for IP addresses instead of domains
453
+ if (/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(parsed.hostname)) {
454
+ violations.push("ip_address_url");
455
+ threats.push("Direct IP address URL");
456
+ riskContribution += 20;
457
+ }
458
+ // Check for suspicious patterns in URL
459
+ if (parsed.href.includes("..") || parsed.href.includes("%00")) {
460
+ violations.push("path_traversal_url");
461
+ threats.push("Path traversal in URL");
462
+ riskContribution += 30;
463
+ }
464
+ // Check for data URLs
465
+ if (url.startsWith("data:")) {
466
+ violations.push("data_url");
467
+ threats.push("Data URL detected");
468
+ riskContribution += 25;
469
+ }
470
+ }
471
+ catch {
472
+ violations.push("invalid_url");
473
+ threats.push("Invalid URL format");
474
+ riskContribution += 30;
475
+ }
476
+ return {
477
+ safe: violations.length === 0,
478
+ violations,
479
+ threats,
480
+ riskContribution,
481
+ };
482
+ }
483
+ generateRecommendations(violations) {
484
+ const recommendations = [];
485
+ if (violations.some((v) => v.includes("metadata"))) {
486
+ recommendations.push("Strip metadata from uploaded files before processing");
487
+ }
488
+ if (violations.some((v) => v.includes("base64"))) {
489
+ recommendations.push("Validate and sanitize base64 payloads before decoding");
490
+ }
491
+ if (violations.some((v) => v.includes("mime"))) {
492
+ recommendations.push("Implement strict MIME type validation");
493
+ }
494
+ if (violations.some((v) => v.includes("steganography"))) {
495
+ recommendations.push("Consider re-encoding images to remove hidden data");
496
+ }
497
+ if (violations.some((v) => v.includes("injection"))) {
498
+ recommendations.push("Sanitize extracted text before including in prompts");
499
+ }
500
+ if (recommendations.length === 0) {
501
+ recommendations.push("Continue monitoring multi-modal inputs");
502
+ }
503
+ return recommendations;
504
+ }
505
+ }
506
+ exports.MultiModalGuard = MultiModalGuard;
507
+ //# sourceMappingURL=multimodal-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multimodal-guard.js","sourceRoot":"","sources":["../../src/guards/multimodal-guard.ts"],"names":[],"mappings":"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"}