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.
- package/LICENSE +21 -0
- package/README.md +318 -0
- package/dist/guards/agent-communication-guard.d.ts +169 -0
- package/dist/guards/agent-communication-guard.d.ts.map +1 -0
- package/dist/guards/agent-communication-guard.js +468 -0
- package/dist/guards/agent-communication-guard.js.map +1 -0
- package/dist/guards/autonomy-escalation-guard.d.ts +137 -0
- package/dist/guards/autonomy-escalation-guard.d.ts.map +1 -0
- package/dist/guards/autonomy-escalation-guard.js +470 -0
- package/dist/guards/autonomy-escalation-guard.js.map +1 -0
- package/dist/guards/circuit-breaker.d.ts +142 -0
- package/dist/guards/circuit-breaker.d.ts.map +1 -0
- package/dist/guards/circuit-breaker.js +347 -0
- package/dist/guards/circuit-breaker.js.map +1 -0
- package/dist/guards/code-execution-guard.d.ts +114 -0
- package/dist/guards/code-execution-guard.d.ts.map +1 -0
- package/dist/guards/code-execution-guard.js +467 -0
- package/dist/guards/code-execution-guard.js.map +1 -0
- package/dist/guards/conversation-guard.d.ts +73 -0
- package/dist/guards/conversation-guard.d.ts.map +1 -0
- package/dist/guards/conversation-guard.js +281 -0
- package/dist/guards/conversation-guard.js.map +1 -0
- package/dist/guards/drift-detector.d.ts +182 -0
- package/dist/guards/drift-detector.d.ts.map +1 -0
- package/dist/guards/drift-detector.js +480 -0
- package/dist/guards/drift-detector.js.map +1 -0
- package/dist/guards/encoding-detector.d.ts +76 -0
- package/dist/guards/encoding-detector.d.ts.map +1 -0
- package/dist/guards/encoding-detector.js +698 -0
- package/dist/guards/encoding-detector.js.map +1 -0
- package/dist/guards/execution-monitor.d.ts +73 -0
- package/dist/guards/execution-monitor.d.ts.map +1 -0
- package/dist/guards/execution-monitor.js +205 -0
- package/dist/guards/execution-monitor.js.map +1 -0
- package/dist/guards/input-sanitizer.d.ts +87 -0
- package/dist/guards/input-sanitizer.d.ts.map +1 -0
- package/dist/guards/input-sanitizer.js +301 -0
- package/dist/guards/input-sanitizer.js.map +1 -0
- package/dist/guards/mcp-security-guard.d.ts +204 -0
- package/dist/guards/mcp-security-guard.d.ts.map +1 -0
- package/dist/guards/mcp-security-guard.js +618 -0
- package/dist/guards/mcp-security-guard.js.map +1 -0
- package/dist/guards/memory-guard.d.ts +124 -0
- package/dist/guards/memory-guard.d.ts.map +1 -0
- package/dist/guards/memory-guard.js +476 -0
- package/dist/guards/memory-guard.js.map +1 -0
- package/dist/guards/multimodal-guard.d.ts +93 -0
- package/dist/guards/multimodal-guard.d.ts.map +1 -0
- package/dist/guards/multimodal-guard.js +507 -0
- package/dist/guards/multimodal-guard.js.map +1 -0
- package/dist/guards/output-filter.d.ts +76 -0
- package/dist/guards/output-filter.d.ts.map +1 -0
- package/dist/guards/output-filter.js +289 -0
- package/dist/guards/output-filter.js.map +1 -0
- package/dist/guards/policy-gate.d.ts +57 -0
- package/dist/guards/policy-gate.d.ts.map +1 -0
- package/dist/guards/policy-gate.js +182 -0
- package/dist/guards/policy-gate.js.map +1 -0
- package/dist/guards/prompt-leakage-guard.d.ts +110 -0
- package/dist/guards/prompt-leakage-guard.d.ts.map +1 -0
- package/dist/guards/prompt-leakage-guard.js +529 -0
- package/dist/guards/prompt-leakage-guard.js.map +1 -0
- package/dist/guards/rag-guard.d.ts +188 -0
- package/dist/guards/rag-guard.d.ts.map +1 -0
- package/dist/guards/rag-guard.js +769 -0
- package/dist/guards/rag-guard.js.map +1 -0
- package/dist/guards/schema-validator.d.ts +35 -0
- package/dist/guards/schema-validator.d.ts.map +1 -0
- package/dist/guards/schema-validator.js +316 -0
- package/dist/guards/schema-validator.js.map +1 -0
- package/dist/guards/state-persistence-guard.d.ts +153 -0
- package/dist/guards/state-persistence-guard.d.ts.map +1 -0
- package/dist/guards/state-persistence-guard.js +484 -0
- package/dist/guards/state-persistence-guard.js.map +1 -0
- package/dist/guards/tenant-boundary.d.ts +67 -0
- package/dist/guards/tenant-boundary.d.ts.map +1 -0
- package/dist/guards/tenant-boundary.js +187 -0
- package/dist/guards/tenant-boundary.js.map +1 -0
- package/dist/guards/tool-chain-validator.d.ts +102 -0
- package/dist/guards/tool-chain-validator.d.ts.map +1 -0
- package/dist/guards/tool-chain-validator.js +480 -0
- package/dist/guards/tool-chain-validator.js.map +1 -0
- package/dist/guards/tool-registry.d.ts +45 -0
- package/dist/guards/tool-registry.d.ts.map +1 -0
- package/dist/guards/tool-registry.js +155 -0
- package/dist/guards/tool-registry.js.map +1 -0
- package/dist/guards/trust-exploitation-guard.d.ts +134 -0
- package/dist/guards/trust-exploitation-guard.d.ts.map +1 -0
- package/dist/guards/trust-exploitation-guard.js +354 -0
- package/dist/guards/trust-exploitation-guard.js.map +1 -0
- package/dist/index.d.ts +133 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +430 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/express.d.ts +119 -0
- package/dist/integrations/express.d.ts.map +1 -0
- package/dist/integrations/express.js +244 -0
- package/dist/integrations/express.js.map +1 -0
- package/dist/integrations/index.d.ts +9 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +26 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/integrations/langchain.d.ts +165 -0
- package/dist/integrations/langchain.d.ts.map +1 -0
- package/dist/integrations/langchain.js +308 -0
- package/dist/integrations/langchain.js.map +1 -0
- package/dist/integrations/openai.d.ts +205 -0
- package/dist/integrations/openai.d.ts.map +1 -0
- package/dist/integrations/openai.js +380 -0
- package/dist/integrations/openai.js.map +1 -0
- package/dist/types/index.d.ts +245 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- 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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"}
|