@weave_protocol/mund 0.1.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 (98) hide show
  1. package/dist/analyzers/code-analyzer.d.ts +24 -0
  2. package/dist/analyzers/code-analyzer.d.ts.map +1 -0
  3. package/dist/analyzers/code-analyzer.js +73 -0
  4. package/dist/analyzers/code-analyzer.js.map +1 -0
  5. package/dist/analyzers/exfiltration-detector.d.ts +40 -0
  6. package/dist/analyzers/exfiltration-detector.d.ts.map +1 -0
  7. package/dist/analyzers/exfiltration-detector.js +220 -0
  8. package/dist/analyzers/exfiltration-detector.js.map +1 -0
  9. package/dist/analyzers/index.d.ts +26 -0
  10. package/dist/analyzers/index.d.ts.map +1 -0
  11. package/dist/analyzers/index.js +61 -0
  12. package/dist/analyzers/index.js.map +1 -0
  13. package/dist/analyzers/injection-detector.d.ts +36 -0
  14. package/dist/analyzers/injection-detector.d.ts.map +1 -0
  15. package/dist/analyzers/injection-detector.js +165 -0
  16. package/dist/analyzers/injection-detector.js.map +1 -0
  17. package/dist/analyzers/pii-detector.d.ts +44 -0
  18. package/dist/analyzers/pii-detector.d.ts.map +1 -0
  19. package/dist/analyzers/pii-detector.js +190 -0
  20. package/dist/analyzers/pii-detector.js.map +1 -0
  21. package/dist/analyzers/secret-scanner.d.ts +32 -0
  22. package/dist/analyzers/secret-scanner.d.ts.map +1 -0
  23. package/dist/analyzers/secret-scanner.js +119 -0
  24. package/dist/analyzers/secret-scanner.js.map +1 -0
  25. package/dist/constants.d.ts +18 -0
  26. package/dist/constants.d.ts.map +1 -0
  27. package/dist/constants.js +580 -0
  28. package/dist/constants.js.map +1 -0
  29. package/dist/index.d.ts +9 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +242 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/notifications/email.d.ts +18 -0
  34. package/dist/notifications/email.d.ts.map +1 -0
  35. package/dist/notifications/email.js +192 -0
  36. package/dist/notifications/email.js.map +1 -0
  37. package/dist/notifications/index.d.ts +51 -0
  38. package/dist/notifications/index.d.ts.map +1 -0
  39. package/dist/notifications/index.js +107 -0
  40. package/dist/notifications/index.js.map +1 -0
  41. package/dist/notifications/slack.d.ts +17 -0
  42. package/dist/notifications/slack.d.ts.map +1 -0
  43. package/dist/notifications/slack.js +128 -0
  44. package/dist/notifications/slack.js.map +1 -0
  45. package/dist/notifications/teams.d.ts +17 -0
  46. package/dist/notifications/teams.d.ts.map +1 -0
  47. package/dist/notifications/teams.js +136 -0
  48. package/dist/notifications/teams.js.map +1 -0
  49. package/dist/notifications/webhook.d.ts +15 -0
  50. package/dist/notifications/webhook.d.ts.map +1 -0
  51. package/dist/notifications/webhook.js +67 -0
  52. package/dist/notifications/webhook.js.map +1 -0
  53. package/dist/storage/index.d.ts +11 -0
  54. package/dist/storage/index.d.ts.map +1 -0
  55. package/dist/storage/index.js +26 -0
  56. package/dist/storage/index.js.map +1 -0
  57. package/dist/storage/memory.d.ts +35 -0
  58. package/dist/storage/memory.d.ts.map +1 -0
  59. package/dist/storage/memory.js +144 -0
  60. package/dist/storage/memory.js.map +1 -0
  61. package/dist/tools/configuration.d.ts +8 -0
  62. package/dist/tools/configuration.d.ts.map +1 -0
  63. package/dist/tools/configuration.js +399 -0
  64. package/dist/tools/configuration.js.map +1 -0
  65. package/dist/tools/index.d.ts +15 -0
  66. package/dist/tools/index.d.ts.map +1 -0
  67. package/dist/tools/index.js +16 -0
  68. package/dist/tools/index.js.map +1 -0
  69. package/dist/tools/monitoring.d.ts +10 -0
  70. package/dist/tools/monitoring.d.ts.map +1 -0
  71. package/dist/tools/monitoring.js +476 -0
  72. package/dist/tools/monitoring.js.map +1 -0
  73. package/dist/types.d.ts +207 -0
  74. package/dist/types.d.ts.map +1 -0
  75. package/dist/types.js +6 -0
  76. package/dist/types.js.map +1 -0
  77. package/package.json +62 -0
  78. package/rules/default.yaml +189 -0
  79. package/src/analyzers/code-analyzer.ts +88 -0
  80. package/src/analyzers/exfiltration-detector.ts +257 -0
  81. package/src/analyzers/index.ts +74 -0
  82. package/src/analyzers/injection-detector.ts +191 -0
  83. package/src/analyzers/pii-detector.ts +220 -0
  84. package/src/analyzers/secret-scanner.ts +142 -0
  85. package/src/constants.ts +603 -0
  86. package/src/index.ts +285 -0
  87. package/src/notifications/email.ts +211 -0
  88. package/src/notifications/index.ts +136 -0
  89. package/src/notifications/slack.ts +170 -0
  90. package/src/notifications/teams.ts +200 -0
  91. package/src/notifications/webhook.ts +80 -0
  92. package/src/storage/index.ts +29 -0
  93. package/src/storage/memory.ts +181 -0
  94. package/src/tools/configuration.ts +478 -0
  95. package/src/tools/index.ts +29 -0
  96. package/src/tools/monitoring.ts +559 -0
  97. package/src/types.ts +300 -0
  98. package/tsconfig.json +24 -0
@@ -0,0 +1,257 @@
1
+ /**
2
+ * Mund - The Guardian Protocol
3
+ * Exfiltration Detector - Detects data exfiltration attempts
4
+ */
5
+
6
+ import {
7
+ type DetectionRule,
8
+ type SecurityIssue,
9
+ type IAnalyzer,
10
+ type IssueLocation
11
+ } from '../types.js';
12
+ import { DANGEROUS_URL_PATTERNS } from '../constants.js';
13
+
14
+ export class ExfiltrationDetector implements IAnalyzer {
15
+ name = 'ExfiltrationDetector';
16
+ type = 'exfiltration';
17
+
18
+ async analyze(content: string, rules: DetectionRule[]): Promise<SecurityIssue[]> {
19
+ const issues: SecurityIssue[] = [];
20
+ const exfilRules = rules.filter(r => r.type === 'exfiltration' && r.enabled);
21
+
22
+ // Pattern-based detection
23
+ for (const rule of exfilRules) {
24
+ if (!rule.pattern) continue;
25
+
26
+ try {
27
+ const regex = new RegExp(rule.pattern, 'gi');
28
+ let match: RegExpExecArray | null;
29
+
30
+ while ((match = regex.exec(content)) !== null) {
31
+ const matchText = match[0];
32
+ const location = this.getLocation(content, match.index, matchText.length);
33
+
34
+ issues.push({
35
+ rule_id: rule.id,
36
+ rule_name: rule.name,
37
+ type: rule.type,
38
+ severity: rule.severity,
39
+ action: rule.action,
40
+ match: this.truncateMatch(matchText),
41
+ location,
42
+ suggestion: this.getSuggestion(rule.id)
43
+ });
44
+ }
45
+ } catch (error) {
46
+ console.error(`Invalid regex pattern in rule ${rule.id}:`, error);
47
+ }
48
+ }
49
+
50
+ // URL extraction and analysis
51
+ const urlIssues = this.analyzeURLs(content);
52
+ issues.push(...urlIssues);
53
+
54
+ // Data encoding detection
55
+ const encodingIssues = this.detectSuspiciousEncoding(content);
56
+ issues.push(...encodingIssues);
57
+
58
+ return issues;
59
+ }
60
+
61
+ /**
62
+ * Extract and analyze URLs in content
63
+ */
64
+ private analyzeURLs(content: string): SecurityIssue[] {
65
+ const issues: SecurityIssue[] = [];
66
+
67
+ // URL regex pattern
68
+ const urlRegex = /https?:\/\/[^\s"'<>)}\]]+/gi;
69
+ let match: RegExpExecArray | null;
70
+
71
+ while ((match = urlRegex.exec(content)) !== null) {
72
+ const url = match[0];
73
+ const location = this.getLocation(content, match.index, url.length);
74
+
75
+ // Check against dangerous patterns
76
+ for (const pattern of DANGEROUS_URL_PATTERNS) {
77
+ if (pattern.test(url)) {
78
+ issues.push({
79
+ rule_id: 'dangerous_url',
80
+ rule_name: 'Dangerous URL Detected',
81
+ type: 'exfiltration',
82
+ severity: 'high',
83
+ action: 'alert',
84
+ match: this.truncateURL(url),
85
+ location,
86
+ suggestion: 'This URL points to a service commonly used for data exfiltration. Verify the destination is legitimate.'
87
+ });
88
+ break;
89
+ }
90
+ }
91
+
92
+ // Check for IP-based URLs
93
+ if (/^https?:\/\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/.test(url)) {
94
+ issues.push({
95
+ rule_id: 'ip_based_url',
96
+ rule_name: 'IP-Based URL',
97
+ type: 'exfiltration',
98
+ severity: 'medium',
99
+ action: 'alert',
100
+ match: this.truncateURL(url),
101
+ location,
102
+ suggestion: 'IP-based URLs can bypass domain-based security controls. Verify this is a legitimate destination.'
103
+ });
104
+ }
105
+
106
+ // Check for data URLs
107
+ if (/^data:/i.test(url)) {
108
+ issues.push({
109
+ rule_id: 'data_url',
110
+ rule_name: 'Data URL Detected',
111
+ type: 'exfiltration',
112
+ severity: 'medium',
113
+ action: 'alert',
114
+ match: this.truncateURL(url),
115
+ location,
116
+ suggestion: 'Data URLs can encode and transfer arbitrary content. Review the embedded data.'
117
+ });
118
+ }
119
+ }
120
+
121
+ return issues;
122
+ }
123
+
124
+ /**
125
+ * Detect suspicious data encoding patterns
126
+ */
127
+ private detectSuspiciousEncoding(content: string): SecurityIssue[] {
128
+ const issues: SecurityIssue[] = [];
129
+
130
+ // Large base64 blocks (potential data exfiltration)
131
+ const base64Regex = /[A-Za-z0-9+/]{100,}={0,2}/g;
132
+ let match: RegExpExecArray | null;
133
+
134
+ while ((match = base64Regex.exec(content)) !== null) {
135
+ const encoded = match[0];
136
+
137
+ // Verify it's likely base64 (not just a long alphanumeric string)
138
+ if (this.isLikelyBase64(encoded)) {
139
+ const location = this.getLocation(content, match.index, encoded.length);
140
+
141
+ issues.push({
142
+ rule_id: 'large_base64_block',
143
+ rule_name: 'Large Base64 Block',
144
+ type: 'exfiltration',
145
+ severity: 'medium',
146
+ action: 'log',
147
+ match: `Base64 block (${encoded.length} chars)`,
148
+ location,
149
+ suggestion: 'Large base64 encoded blocks may contain exfiltrated data. Review the decoded content.'
150
+ });
151
+ }
152
+ }
153
+
154
+ // Hex-encoded data blocks
155
+ const hexRegex = /(?:0x)?[0-9a-fA-F]{200,}/g;
156
+ while ((match = hexRegex.exec(content)) !== null) {
157
+ const encoded = match[0];
158
+ const location = this.getLocation(content, match.index, encoded.length);
159
+
160
+ issues.push({
161
+ rule_id: 'large_hex_block',
162
+ rule_name: 'Large Hex-Encoded Block',
163
+ type: 'exfiltration',
164
+ severity: 'low',
165
+ action: 'log',
166
+ match: `Hex block (${encoded.length} chars)`,
167
+ location,
168
+ suggestion: 'Large hex-encoded blocks may contain encoded data. Review the decoded content.'
169
+ });
170
+ }
171
+
172
+ return issues;
173
+ }
174
+
175
+ /**
176
+ * Check if string is likely base64
177
+ */
178
+ private isLikelyBase64(str: string): boolean {
179
+ // Check character distribution
180
+ const chars = new Set(str.replace(/=/g, ''));
181
+
182
+ // Base64 uses a specific character set
183
+ const base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
184
+ for (const char of chars) {
185
+ if (!base64Chars.includes(char)) return false;
186
+ }
187
+
188
+ // Check if it decodes to valid content
189
+ try {
190
+ const decoded = Buffer.from(str, 'base64').toString('utf8');
191
+ // Check if decoded content has a reasonable ratio of printable characters
192
+ const printable = decoded.replace(/[^\x20-\x7E]/g, '').length;
193
+ return printable / decoded.length > 0.7;
194
+ } catch {
195
+ return false;
196
+ }
197
+ }
198
+
199
+ /**
200
+ * Calculate location within content
201
+ */
202
+ private getLocation(content: string, start: number, length: number): IssueLocation {
203
+ const end = start + length;
204
+ const lines = content.substring(0, start).split('\n');
205
+ const line = lines.length;
206
+ const column = lines[lines.length - 1].length + 1;
207
+ return { start, end, line, column };
208
+ }
209
+
210
+ /**
211
+ * Truncate match for display
212
+ */
213
+ private truncateMatch(match: string, maxLength = 100): string {
214
+ if (match.length <= maxLength) return match;
215
+ return match.substring(0, maxLength) + '...';
216
+ }
217
+
218
+ /**
219
+ * Truncate URL for display (hide potential sensitive parts)
220
+ */
221
+ private truncateURL(url: string, maxLength = 80): string {
222
+ try {
223
+ const parsed = new URL(url);
224
+ const base = `${parsed.protocol}//${parsed.host}`;
225
+
226
+ if (base.length >= maxLength) {
227
+ return base.substring(0, maxLength) + '...';
228
+ }
229
+
230
+ const remainingLength = maxLength - base.length;
231
+ const path = parsed.pathname + parsed.search;
232
+
233
+ if (path.length > remainingLength) {
234
+ return base + path.substring(0, remainingLength) + '...';
235
+ }
236
+
237
+ return base + path;
238
+ } catch {
239
+ return url.substring(0, maxLength) + (url.length > maxLength ? '...' : '');
240
+ }
241
+ }
242
+
243
+ /**
244
+ * Get remediation suggestion
245
+ */
246
+ private getSuggestion(ruleId: string): string {
247
+ const suggestions: Record<string, string> = {
248
+ suspicious_url_post: 'This code sends data to a service commonly used for data capture. Verify the destination.',
249
+ dns_exfiltration: 'DNS queries with encoded data can be used for exfiltration. Monitor and restrict DNS access.',
250
+ data_encoding_suspicious: 'Encoding sensitive data before transmission may indicate exfiltration. Review the purpose.',
251
+ };
252
+
253
+ return suggestions[ruleId] || 'Review this pattern for potential data exfiltration.';
254
+ }
255
+ }
256
+
257
+ export default ExfiltrationDetector;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Mund - The Guardian Protocol
3
+ * Analyzers Index - Exports all analyzer modules
4
+ */
5
+
6
+ export { SecretScanner } from './secret-scanner.js';
7
+ export { PIIDetector } from './pii-detector.js';
8
+ export { CodeAnalyzer } from './code-analyzer.js';
9
+ export { InjectionDetector } from './injection-detector.js';
10
+ export { ExfiltrationDetector } from './exfiltration-detector.js';
11
+
12
+ import { SecretScanner } from './secret-scanner.js';
13
+ import { PIIDetector } from './pii-detector.js';
14
+ import { CodeAnalyzer } from './code-analyzer.js';
15
+ import { InjectionDetector } from './injection-detector.js';
16
+ import { ExfiltrationDetector } from './exfiltration-detector.js';
17
+ import type { IAnalyzer } from '../types.js';
18
+
19
+ /**
20
+ * Get all available analyzers
21
+ */
22
+ export function getAnalyzers(): IAnalyzer[] {
23
+ return [
24
+ new SecretScanner(),
25
+ new PIIDetector(),
26
+ new CodeAnalyzer(),
27
+ new InjectionDetector(),
28
+ new ExfiltrationDetector()
29
+ ];
30
+ }
31
+
32
+ /**
33
+ * Create analyzer engine that runs all analyzers
34
+ */
35
+ export class AnalyzerEngine {
36
+ private analyzers: IAnalyzer[];
37
+
38
+ constructor(analyzers?: IAnalyzer[]) {
39
+ this.analyzers = analyzers || getAnalyzers();
40
+ }
41
+
42
+ async analyzeAll(content: string, rules: import('../types.js').DetectionRule[]): Promise<import('../types.js').SecurityIssue[]> {
43
+ const allIssues: import('../types.js').SecurityIssue[] = [];
44
+
45
+ for (const analyzer of this.analyzers) {
46
+ try {
47
+ const issues = await analyzer.analyze(content, rules);
48
+ allIssues.push(...issues);
49
+ } catch (error) {
50
+ console.error(`Error in analyzer ${analyzer.name}:`, error);
51
+ }
52
+ }
53
+
54
+ // Sort by severity (critical first)
55
+ const severityOrder = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };
56
+ allIssues.sort((a, b) =>
57
+ (severityOrder[a.severity] || 4) - (severityOrder[b.severity] || 4)
58
+ );
59
+
60
+ return allIssues;
61
+ }
62
+
63
+ addAnalyzer(analyzer: IAnalyzer): void {
64
+ this.analyzers.push(analyzer);
65
+ }
66
+
67
+ removeAnalyzer(name: string): void {
68
+ this.analyzers = this.analyzers.filter(a => a.name !== name);
69
+ }
70
+
71
+ getAnalyzerNames(): string[] {
72
+ return this.analyzers.map(a => a.name);
73
+ }
74
+ }
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Mund - The Guardian Protocol
3
+ * Injection Detector - Detects prompt injection attempts
4
+ */
5
+
6
+ import {
7
+ type DetectionRule,
8
+ type SecurityIssue,
9
+ type IAnalyzer,
10
+ type IssueLocation
11
+ } from '../types.js';
12
+
13
+ export class InjectionDetector implements IAnalyzer {
14
+ name = 'InjectionDetector';
15
+ type = 'injection';
16
+
17
+ async analyze(content: string, rules: DetectionRule[]): Promise<SecurityIssue[]> {
18
+ const issues: SecurityIssue[] = [];
19
+ const injectionRules = rules.filter(r => r.type === 'injection' && r.enabled);
20
+
21
+ // Normalize content for detection
22
+ const normalizedContent = this.normalizeContent(content);
23
+
24
+ for (const rule of injectionRules) {
25
+ if (!rule.pattern) continue;
26
+
27
+ try {
28
+ const regex = new RegExp(rule.pattern, 'gi');
29
+ let match: RegExpExecArray | null;
30
+
31
+ while ((match = regex.exec(normalizedContent)) !== null) {
32
+ const matchText = match[0];
33
+ const location = this.getLocation(content, match.index, matchText.length);
34
+
35
+ issues.push({
36
+ rule_id: rule.id,
37
+ rule_name: rule.name,
38
+ type: rule.type,
39
+ severity: rule.severity,
40
+ action: rule.action,
41
+ match: this.sanitizeMatch(matchText),
42
+ location,
43
+ suggestion: this.getSuggestion(rule.id)
44
+ });
45
+ }
46
+ } catch (error) {
47
+ console.error(`Invalid regex pattern in rule ${rule.id}:`, error);
48
+ }
49
+ }
50
+
51
+ // Additional heuristic checks
52
+ const heuristicIssues = this.heuristicAnalysis(content);
53
+ issues.push(...heuristicIssues);
54
+
55
+ return issues;
56
+ }
57
+
58
+ /**
59
+ * Normalize content to detect obfuscated injection attempts
60
+ */
61
+ private normalizeContent(content: string): string {
62
+ return content
63
+ // Remove zero-width characters
64
+ .replace(/[\u200B-\u200D\uFEFF]/g, '')
65
+ // Normalize Unicode variations
66
+ .normalize('NFKC')
67
+ // Collapse multiple spaces
68
+ .replace(/\s+/g, ' ')
69
+ // Remove common obfuscation characters
70
+ .replace(/[^\w\s.,!?'"()-]/g, ' ');
71
+ }
72
+
73
+ /**
74
+ * Heuristic analysis for injection patterns
75
+ */
76
+ private heuristicAnalysis(content: string): SecurityIssue[] {
77
+ const issues: SecurityIssue[] = [];
78
+
79
+ // Check for role switching attempts
80
+ const roleSwitchPatterns = [
81
+ /\bsystem\s*:\s*you\s+are/i,
82
+ /\bassistant\s*:\s*i\s+(will|can|am)/i,
83
+ /\[system\]/i,
84
+ /\<\|?system\|?\>/i,
85
+ /\{system_prompt\}/i,
86
+ ];
87
+
88
+ for (const pattern of roleSwitchPatterns) {
89
+ const match = content.match(pattern);
90
+ if (match) {
91
+ issues.push({
92
+ rule_id: 'heuristic_role_switch',
93
+ rule_name: 'Role Switching Attempt',
94
+ type: 'injection',
95
+ severity: 'high' as const,
96
+ action: 'alert' as const,
97
+ match: this.sanitizeMatch(match[0]),
98
+ suggestion: 'This content appears to attempt to inject role-switching markers.'
99
+ });
100
+ }
101
+ }
102
+
103
+ // Check for markdown/code injection that might alter rendering
104
+ const markdownPatterns = [
105
+ /```\s*system/i,
106
+ /\<script\>/i,
107
+ /javascript:/i,
108
+ /data:text\/html/i,
109
+ ];
110
+
111
+ for (const pattern of markdownPatterns) {
112
+ const match = content.match(pattern);
113
+ if (match) {
114
+ issues.push({
115
+ rule_id: 'heuristic_markup_injection',
116
+ rule_name: 'Markup Injection Attempt',
117
+ type: 'injection',
118
+ severity: 'medium' as const,
119
+ action: 'alert' as const,
120
+ match: this.sanitizeMatch(match[0]),
121
+ suggestion: 'This content contains potentially dangerous markup or code injection.'
122
+ });
123
+ }
124
+ }
125
+
126
+ // Check for excessive special characters (potential obfuscation)
127
+ const specialCharRatio = this.calculateSpecialCharRatio(content);
128
+ if (specialCharRatio > 0.3 && content.length > 50) {
129
+ issues.push({
130
+ rule_id: 'heuristic_obfuscation',
131
+ rule_name: 'Potential Obfuscation',
132
+ type: 'injection',
133
+ severity: 'low' as const,
134
+ action: 'log' as const,
135
+ match: `Special character ratio: ${(specialCharRatio * 100).toFixed(1)}%`,
136
+ suggestion: 'This content has an unusually high ratio of special characters, which may indicate obfuscation.'
137
+ });
138
+ }
139
+
140
+ return issues;
141
+ }
142
+
143
+ /**
144
+ * Calculate ratio of special characters
145
+ */
146
+ private calculateSpecialCharRatio(content: string): number {
147
+ if (content.length === 0) return 0;
148
+ const specialChars = content.replace(/[\w\s]/g, '').length;
149
+ return specialChars / content.length;
150
+ }
151
+
152
+ /**
153
+ * Calculate location within content
154
+ */
155
+ private getLocation(content: string, start: number, length: number): IssueLocation {
156
+ const end = start + length;
157
+ const lines = content.substring(0, start).split('\n');
158
+ const line = lines.length;
159
+ const column = lines[lines.length - 1].length + 1;
160
+ return { start, end, line, column };
161
+ }
162
+
163
+ /**
164
+ * Sanitize match for safe display
165
+ */
166
+ private sanitizeMatch(match: string, maxLength = 100): string {
167
+ const sanitized = match
168
+ .replace(/</g, '&lt;')
169
+ .replace(/>/g, '&gt;')
170
+ .replace(/"/g, '&quot;');
171
+
172
+ if (sanitized.length <= maxLength) return sanitized;
173
+ return sanitized.substring(0, maxLength) + '...';
174
+ }
175
+
176
+ /**
177
+ * Get remediation suggestion
178
+ */
179
+ private getSuggestion(ruleId: string): string {
180
+ const suggestions: Record<string, string> = {
181
+ prompt_injection_ignore: 'This content attempts to make the AI ignore its instructions. Do not process user inputs that contain such patterns.',
182
+ prompt_injection_jailbreak: 'This appears to be a jailbreak attempt. Such content should be filtered or rejected.',
183
+ prompt_injection_system: 'This content attempts to extract system prompts. Do not reveal system instructions.',
184
+ prompt_injection_roleplay: 'This content attempts to manipulate behavior through roleplay. Apply content filtering.',
185
+ };
186
+
187
+ return suggestions[ruleId] || 'This content shows signs of injection attacks. Review and sanitize input.';
188
+ }
189
+ }
190
+
191
+ export default InjectionDetector;