agentshield-sdk 13.2.0 → 13.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentshield-sdk",
3
- "version": "13.2.0",
3
+ "version": "13.5.0",
4
4
  "description": "SOTA AI agent security SDK. F1 1.000 on BIPIA/HackAPrompt/MCPTox/Multilingual benchmarks. 400+ exports, 100+ modules. Zero dependencies, runs locally.",
5
5
  "main": "src/main.js",
6
6
  "types": "types/index.d.ts",
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "sideEffects": false,
34
34
  "scripts": {
35
- "test": "node test/test.js && node test/test-modules.js && node test/test-new-features.js && node test/test-mcp-guard.js && node test/test-supply-chain-scanner.js && node test/test-owasp-agentic.js && node test/test-redteam-cli.js && node test/test-drift-monitor.js && node test/test-micro-model.js && node test/test-level5.js && node test/test-sota.js && node test/test-cross-turn.js && node test/test-v12.js && node test/test-traps.js && node test/test-deepmind.js",
35
+ "test": "node test/test.js && node test/test-modules.js && node test/test-new-features.js && node test/test-mcp-guard.js && node test/test-supply-chain-scanner.js && node test/test-owasp-agentic.js && node test/test-redteam-cli.js && node test/test-drift-monitor.js && node test/test-micro-model.js && node test/test-level5.js && node test/test-sota.js && node test/test-cross-turn.js && node test/test-v12.js && node test/test-traps.js && node test/test-deepmind.js && node test/test-render-differential.js && node test/test-sybil.js && node test/test-side-channel.js",
36
36
  "test:new-products": "node test/test-mcp-guard.js && node test/test-supply-chain-scanner.js && node test/test-owasp-agentic.js && node test/test-redteam-cli.js && node test/test-drift-monitor.js && node test/test-micro-model.js",
37
37
  "test:all": "node test/test-all-40-features.js",
38
38
  "test:mcp": "node test/test-mcp-security.js",
@@ -584,8 +584,10 @@ class ImmutableAuditLog {
584
584
  * @param {number} [options.maxAge=0] - Maximum age in milliseconds (0 = unlimited).
585
585
  * @param {function} [options.archiveCallback] - Called with removed entries during retention enforcement. Signature: (entries: AuditEntry[]) => void.
586
586
  * @param {string} [options.genesisHash] - Custom genesis hash (defaults to GENESIS_HASH).
587
+ * @param {boolean} [options.sanitizeLogs=false] - Redact sensitive content (emails, SSNs, API keys) before writing to the chain.
587
588
  */
588
589
  constructor(options = {}) {
590
+ this.options = options;
589
591
  this._store = options.store || new MemoryStore();
590
592
  this._maxEntries = options.maxEntries || 0;
591
593
  this._maxAge = options.maxAge || 0;
@@ -598,6 +600,59 @@ class ImmutableAuditLog {
598
600
  console.log('[Agent Shield] ImmutableAuditLog initialized (store: %s)', this._store.constructor.name);
599
601
  }
600
602
 
603
+ /**
604
+ * Sanitize an entry's data object by redacting sensitive content.
605
+ * Addresses the security scan finding about audit logs containing sensitive prompt data.
606
+ *
607
+ * Redacts:
608
+ * - Email addresses -> [EMAIL_REDACTED]
609
+ * - SSN patterns (XXX-XX-XXXX) -> [SSN_REDACTED]
610
+ * - API key patterns (sk-..., key-..., token-...) -> [KEY_REDACTED]
611
+ * - Truncates 'content' and 'input' fields to 500 characters max
612
+ *
613
+ * @param {object} entry - The data object to sanitize.
614
+ * @returns {object} A sanitized copy of the data object.
615
+ */
616
+ sanitize(entry) {
617
+ if (!this.options.sanitizeLogs) {
618
+ return entry;
619
+ }
620
+
621
+ const sanitized = JSON.parse(JSON.stringify(entry));
622
+
623
+ const redactString = (str) => {
624
+ if (typeof str !== 'string') return str;
625
+ // Redact email addresses
626
+ str = str.replace(/[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/g, '[EMAIL_REDACTED]');
627
+ // Redact SSN patterns (XXX-XX-XXXX)
628
+ str = str.replace(/\b\d{3}-\d{2}-\d{4}\b/g, '[SSN_REDACTED]');
629
+ // Redact API key patterns (sk-..., key-..., token-...)
630
+ str = str.replace(/\b(?:sk|key|token)-[a-zA-Z0-9_\-]{8,}\b/g, '[KEY_REDACTED]');
631
+ return str;
632
+ };
633
+
634
+ const redactObject = (obj) => {
635
+ if (obj === null || obj === undefined) return obj;
636
+ if (typeof obj === 'string') return redactString(obj);
637
+ if (Array.isArray(obj)) return obj.map(item => redactObject(item));
638
+ if (typeof obj === 'object') {
639
+ const result = {};
640
+ for (const key of Object.keys(obj)) {
641
+ let value = redactObject(obj[key]);
642
+ // Truncate content and input fields to 500 chars
643
+ if ((key === 'content' || key === 'input') && typeof value === 'string' && value.length > 500) {
644
+ value = value.slice(0, 500) + '...[TRUNCATED]';
645
+ }
646
+ result[key] = value;
647
+ }
648
+ return result;
649
+ }
650
+ return obj;
651
+ };
652
+
653
+ return redactObject(sanitized);
654
+ }
655
+
601
656
  /**
602
657
  * Initialize sequence counter from existing store data.
603
658
  * @private
@@ -646,12 +701,15 @@ class ImmutableAuditLog {
646
701
  delete normalizedActor.name;
647
702
  }
648
703
 
704
+ // Sanitize data if sanitizeLogs is enabled
705
+ const sanitizedData = this.sanitize(data || {});
706
+
649
707
  const entryContent = {
650
708
  id,
651
709
  sequence: this._sequence,
652
710
  timestamp,
653
711
  type,
654
- data: data || {},
712
+ data: sanitizedData,
655
713
  actor: normalizedActor
656
714
  };
657
715
 
package/src/audit.js CHANGED
@@ -602,7 +602,7 @@ function runAuditCLI() {
602
602
  });
603
603
 
604
604
  const report = audit.run();
605
- console.log('[Agent Shield] Audit Report:\n' + report.formatReport());
605
+ console.log('[Agent Shield]', report.formatReport());
606
606
  return report;
607
607
  }
608
608
 
package/src/cross-turn.js CHANGED
@@ -29,6 +29,12 @@ const ESCALATION_SIGNALS = [
29
29
  /(?:one\s+more\s+(?:thing|question|step)|just\s+one\s+(?:last|final)\s+(?:thing|question))/i,
30
30
  /(?:can\s+you\s+go\s+(?:a\s+little\s+)?(?:further|deeper)|take\s+(?:it|this)\s+(?:a\s+step\s+)?further)/i,
31
31
  /(?:you\s+(?:just|already)\s+(?:showed|told|gave)\s+me|you\s+(?:were|seemed)\s+(?:willing|happy)\s+to)/i,
32
+ // Crescendo attack patterns — benign start that gradually escalates
33
+ /(?:hypothetically|in\s+theory|for\s+(?:educational|research|academic)\s+purposes)/i,
34
+ /(?:let's\s+(?:say|imagine|pretend)|what\s+if\s+(?:someone|a\s+person|we))/i,
35
+ /(?:I\s+(?:know|understand)\s+you\s+(?:can't|shouldn't)\s+but|normally\s+you\s+(?:wouldn't|can't)\s+but)/i,
36
+ /(?:you\s+(?:helped|assisted)\s+(?:me|us)\s+(?:before|last\s+time|earlier)\s+with\s+(?:something\s+)?similar)/i,
37
+ /(?:this\s+is\s+(?:similar|related)\s+to\s+what\s+(?:you|we)\s+(?:did|discussed))/i,
32
38
  ];
33
39
 
34
40
  /** Trust erosion patterns — attempts to lower the model's guard over turns. */
@@ -165,7 +171,25 @@ class ConversationTracker {
165
171
  }
166
172
  }
167
173
 
168
- // 5. Authority accumulationuser references previous "agreements"
174
+ // 5. Crescendo detectionbenign conversation gradually introduces sensitive framing
175
+ if (role === 'user' && this.turns.length >= 5) {
176
+ const window = this.turns.slice(-6, -1).filter(t => t.role === 'user');
177
+ const hypotheticalCount = window.filter(t =>
178
+ /(?:hypothetically|in\s+theory|let's\s+(?:say|imagine)|what\s+if|for\s+(?:educational|research)\s+purposes)/i.test(t.content)
179
+ ).length;
180
+ if (hypotheticalCount >= 2 && (topic === 'sensitive' || topic === 'dangerous')) {
181
+ turnAlerts.push({
182
+ type: 'crescendo_attack',
183
+ severity: 'high',
184
+ turnIndex: turn.turnIndex,
185
+ hypotheticalCount,
186
+ currentTopic: topic,
187
+ description: `Crescendo pattern: ${hypotheticalCount} hypothetical/theoretical framings followed by ${topic} topic. Gradual normalization of sensitive requests.`
188
+ });
189
+ }
190
+ }
191
+
192
+ // 6. Authority accumulation — user references previous "agreements"
169
193
  if (role === 'user' && /(?:you\s+(?:said|agreed|confirmed|told\s+me)|as\s+we\s+(?:discussed|agreed)|per\s+our\s+(?:agreement|conversation))/i.test(content)) {
170
194
  const hasRealAgreement = this.turns.some(t => t.role === 'assistant' && /(?:sure|yes|okay|of\s+course|I\s+(?:can|will))/i.test(t.content));
171
195
  if (!hasRealAgreement) {
@@ -2206,6 +2206,204 @@ const INJECTION_PATTERNS = [
2206
2206
  category: 'indirect_injection',
2207
2207
  description: 'Text contains a "note to AI" directive hidden in external content.',
2208
2208
  detail: 'Annotation injection: uses "note to AI" framing to inject instructions into tool output or document content.'
2209
+ },
2210
+
2211
+ // --- XSS in Agent Output ---
2212
+ {
2213
+ regex: /<script[^>]*>.*?<\/script>/is,
2214
+ severity: 'high',
2215
+ category: 'xss_injection',
2216
+ description: 'Detects script tag XSS payloads embedded in AI agent output.',
2217
+ detail: 'Script tag injection: attackers embed XSS in prompt injections so AI-generated HTML executes malicious code in downstream consumers.'
2218
+ },
2219
+ {
2220
+ regex: /on(error|load|click|mouseover)\s*=\s*["'][^"']*["']/i,
2221
+ severity: 'high',
2222
+ category: 'xss_injection',
2223
+ description: 'Detects event handler XSS payloads embedded in AI agent output.',
2224
+ detail: 'Event handler injection: attackers embed XSS event handlers in prompt injections so AI-generated HTML executes malicious code on user interaction.'
2225
+ },
2226
+ {
2227
+ regex: /javascript\s*:/i,
2228
+ severity: 'high',
2229
+ category: 'xss_injection',
2230
+ description: 'Detects JavaScript URI scheme XSS payloads embedded in AI agent output.',
2231
+ detail: 'JavaScript URI injection: attackers embed javascript: URIs in prompt injections so AI-generated links execute malicious code when clicked.'
2232
+ },
2233
+ {
2234
+ regex: /<iframe[^>]*src\s*=\s*["'](?!about:blank)/i,
2235
+ severity: 'high',
2236
+ category: 'xss_injection',
2237
+ description: 'Detects iframe injection with external source in AI agent output.',
2238
+ detail: 'Iframe injection: attackers embed iframes with external sources in prompt injections so AI-generated HTML loads malicious content from attacker-controlled domains.'
2239
+ },
2240
+ {
2241
+ regex: /<img[^>]*onerror\s*=/i,
2242
+ severity: 'high',
2243
+ category: 'xss_injection',
2244
+ description: 'Detects image error handler XSS payloads embedded in AI agent output.',
2245
+ detail: 'Image onerror injection: attackers embed img tags with onerror handlers in prompt injections so AI-generated HTML executes malicious code when the image fails to load.'
2246
+ },
2247
+
2248
+ // --- Acrostic / Steganographic Injection ---
2249
+ {
2250
+ regex: /^[iI].*\n[gG].*\n[nN].*\n[oO].*\n[rR].*\n[eE]/m,
2251
+ severity: 'medium',
2252
+ category: 'steganographic_injection',
2253
+ description: 'Detects hidden instructions spelled out across line-initial characters (acrostic attacks spelling "ignore").',
2254
+ detail: 'Acrostic injection: researchers demonstrated 93% evasion success rate with steganographic techniques where first characters of consecutive lines spell out injection keywords like "ignore".'
2255
+ },
2256
+ {
2257
+ regex: /^[sS].*\n[yY].*\n[sS].*\n[tT].*\n[eE].*\n[mM]/m,
2258
+ severity: 'medium',
2259
+ category: 'steganographic_injection',
2260
+ description: 'Detects hidden instructions spelled out across line-initial characters (acrostic attacks spelling "system").',
2261
+ detail: 'Acrostic injection: researchers demonstrated 93% evasion success rate with steganographic techniques where first characters of consecutive lines spell out injection keywords like "system".'
2262
+ },
2263
+
2264
+ // --- MCP Config Command Injection ---
2265
+ {
2266
+ regex: /mcp\.json.*[;&|`$]/i,
2267
+ severity: 'critical',
2268
+ category: 'mcp_config_injection',
2269
+ description: 'Detects command injection in MCP configuration files (CVE-2026-21518).',
2270
+ detail: 'MCP config injection: attackers inject shell metacharacters into mcp.json references to achieve command execution via the VS Code mcp.json attack vector.'
2271
+ },
2272
+ {
2273
+ regex: /"(?:command|args)":\s*"[^"]*[;&|`$()]/i,
2274
+ severity: 'critical',
2275
+ category: 'mcp_config_injection',
2276
+ description: 'Detects command injection in MCP tool configuration fields (CVE-2026-21518).',
2277
+ detail: 'MCP tool config injection: attackers inject shell metacharacters into MCP tool command/args fields to achieve command execution via the VS Code mcp.json attack vector.'
2278
+ },
2279
+
2280
+ // --- Offensive Agent Behavior ---
2281
+ {
2282
+ regex: /(?:scan|enumerate|exploit|pivot|lateral\s*move|exfiltrate).*(?:target|victim|host|network|server)/i,
2283
+ severity: 'critical',
2284
+ category: 'offensive_agent',
2285
+ description: 'Detects AI agents being used as attack tools for automated exploitation.',
2286
+ detail: 'Automated exploitation language: references 2026 incidents where AI agents compromised 600+ firewalls autonomously using scan/exploit/pivot chains against target infrastructure.'
2287
+ },
2288
+ {
2289
+ regex: /(?:reverse\s*shell|bind\s*shell|c2|command\s*and\s*control|beacon)/i,
2290
+ severity: 'critical',
2291
+ category: 'offensive_agent',
2292
+ description: 'Detects AI agents being instructed to set up C2 or attack infrastructure.',
2293
+ detail: 'C2/attack infrastructure: references 2026 incidents where AI agents compromised 600+ firewalls autonomously by establishing reverse shells and command-and-control channels.'
2294
+ },
2295
+ {
2296
+ regex: /(?:dump|harvest|steal)\s*(?:credentials?|passwords?|hashes?|tokens?|keys?)/i,
2297
+ severity: 'critical',
2298
+ category: 'offensive_agent',
2299
+ description: 'Detects AI agents being used for credential theft operations.',
2300
+ detail: 'Credential theft operations: references 2026 incidents where AI agents compromised 600+ firewalls autonomously and harvested credentials for lateral movement.'
2301
+ },
2302
+
2303
+ // --- Cloud IAM Overpermission ---
2304
+ {
2305
+ regex: /"(?:Action|Effect)":\s*"\*"/i,
2306
+ severity: 'high',
2307
+ category: 'cloud_overpermission',
2308
+ description: 'Detects overpermissioned cloud IAM policies with wildcard Action/Effect that enable "Agent God Mode" attacks.',
2309
+ detail: 'IAM wildcard permissions: Palo Alto Unit 42 discovered AWS AgentCore attack where wildcard IAM policies enable cross-agent data access and full account takeover.'
2310
+ },
2311
+ {
2312
+ regex: /arn:aws:[^"]*:\*/i,
2313
+ severity: 'high',
2314
+ category: 'cloud_overpermission',
2315
+ description: 'Detects AWS ARN references with wildcard resources that enable "Agent God Mode" attacks.',
2316
+ detail: 'AWS ARN wildcard resource: Palo Alto Unit 42 discovered AWS AgentCore attack where wildcard resource ARNs enable cross-agent data access across all resources in a service.'
2317
+ },
2318
+ {
2319
+ regex: /"Resource":\s*"\*"/i,
2320
+ severity: 'high',
2321
+ category: 'cloud_overpermission',
2322
+ description: 'Detects overpermissioned cloud IAM policies with wildcard Resource that enable "Agent God Mode" attacks.',
2323
+ detail: 'IAM resource wildcard: Palo Alto Unit 42 discovered AWS AgentCore attack where wildcard Resource policies enable cross-agent data access to all AWS resources.'
2324
+ },
2325
+
2326
+ // --- Encoding Chain Detection ---
2327
+ {
2328
+ regex: /(?:atob|decode|base64)\s*\(\s*['"][A-Za-z0-9+\/=]{50,}['"]\s*\)/i,
2329
+ severity: 'high',
2330
+ category: 'encoding_chain',
2331
+ description: 'Detects multi-layer encoding chains used to evade security scanners',
2332
+ detail: 'Encoding chain evasion: attackers nest base64 inside unicode inside URL encoding to bypass single-layer decoders'
2333
+ },
2334
+ {
2335
+ regex: /\\u[0-9a-fA-F]{4}(?:\\u[0-9a-fA-F]{4}){10,}/,
2336
+ severity: 'medium',
2337
+ category: 'encoding_chain',
2338
+ description: 'Detects multi-layer encoding chains used to evade security scanners',
2339
+ detail: 'Encoding chain evasion: attackers nest base64 inside unicode inside URL encoding to bypass single-layer decoders'
2340
+ },
2341
+ {
2342
+ regex: /(?:%[0-9a-fA-F]{2}){20,}/,
2343
+ severity: 'medium',
2344
+ category: 'encoding_chain',
2345
+ description: 'Detects multi-layer encoding chains used to evade security scanners',
2346
+ detail: 'Encoding chain evasion: attackers nest base64 inside unicode inside URL encoding to bypass single-layer decoders'
2347
+ },
2348
+
2349
+ // --- SVG-Based Injection ---
2350
+ {
2351
+ regex: /<svg[^>]*>[\s\S]*?(?:ignore|override|system|instructions)[\s\S]*?<\/svg>/i,
2352
+ severity: 'high',
2353
+ category: 'svg_injection',
2354
+ description: 'Detects prompt injection hidden in SVG elements',
2355
+ detail: 'SVG injection: Unit 42 found real-world attacks using SVG encapsulation with 24 separate injection attempts layered in zero-sized fonts, off-screen positioning, and CSS suppression'
2356
+ },
2357
+ {
2358
+ regex: /<foreignObject[^>]*>[\s\S]*?(?:ignore|override|forget|disregard)[\s\S]*?<\/foreignObject>/i,
2359
+ severity: 'high',
2360
+ category: 'svg_injection',
2361
+ description: 'Detects prompt injection hidden in SVG elements',
2362
+ detail: 'SVG injection: Unit 42 found real-world attacks using SVG encapsulation with 24 separate injection attempts layered in zero-sized fonts, off-screen positioning, and CSS suppression'
2363
+ },
2364
+ {
2365
+ regex: /<text[^>]*(?:opacity\s*[:=]\s*0|display\s*[:=]\s*none|font-size\s*[:=]\s*0)[^>]*>/i,
2366
+ severity: 'high',
2367
+ category: 'svg_injection',
2368
+ description: 'Detects prompt injection hidden in SVG elements',
2369
+ detail: 'SVG injection: Unit 42 found real-world attacks using SVG encapsulation with 24 separate injection attempts layered in zero-sized fonts, off-screen positioning, and CSS suppression'
2370
+ },
2371
+ {
2372
+ regex: /<desc[^>]*>[\s\S]*?(?:ignore|system|instruction|override)[\s\S]*?<\/desc>/i,
2373
+ severity: 'medium',
2374
+ category: 'svg_injection',
2375
+ description: 'Detects prompt injection hidden in SVG elements',
2376
+ detail: 'SVG injection: Unit 42 found real-world attacks using SVG encapsulation with 24 separate injection attempts layered in zero-sized fonts, off-screen positioning, and CSS suppression'
2377
+ },
2378
+
2379
+ // --- Structured Data Injection ---
2380
+ {
2381
+ regex: /["'](?:__comment|_note|description|help_text)["']\s*:\s*["'][^"']*(?:ignore|override|system|instructions)[^"']*["']/i,
2382
+ severity: 'high',
2383
+ category: 'structured_data_injection',
2384
+ description: 'Detects prompt injection hidden in structured data formats',
2385
+ detail: 'Structured data injection: agents constantly parse JSON/XML/YAML/CSV and attackers embed instructions in metadata fields, CDATA sections, and comments'
2386
+ },
2387
+ {
2388
+ regex: /<!\[CDATA\[[\s\S]*?(?:ignore|override|system|instructions)[\s\S]*?\]\]>/i,
2389
+ severity: 'high',
2390
+ category: 'structured_data_injection',
2391
+ description: 'Detects prompt injection hidden in structured data formats',
2392
+ detail: 'Structured data injection: agents constantly parse JSON/XML/YAML/CSV and attackers embed instructions in metadata fields, CDATA sections, and comments'
2393
+ },
2394
+ {
2395
+ regex: /^#.*(?:ignore|override|system|instructions)/im,
2396
+ severity: 'medium',
2397
+ category: 'structured_data_injection',
2398
+ description: 'Detects prompt injection hidden in structured data formats',
2399
+ detail: 'Structured data injection: agents constantly parse JSON/XML/YAML/CSV and attackers embed instructions in metadata fields, CDATA sections, and comments'
2400
+ },
2401
+ {
2402
+ regex: /(?:<!--|\{\{!--|\/\*|#)\s*(?:ignore|override|forget|disregard)\s*(?:all\s+)?(?:previous|prior|above)/i,
2403
+ severity: 'high',
2404
+ category: 'structured_data_injection',
2405
+ description: 'Detects prompt injection hidden in structured data formats',
2406
+ detail: 'Structured data injection: agents constantly parse JSON/XML/YAML/CSV and attackers embed instructions in metadata fields, CDATA sections, and comments'
2209
2407
  }
2210
2408
  ];
2211
2409
 
@@ -564,11 +564,13 @@ class DocumentScanner {
564
564
  * @param {string} [options.sensitivity='medium'] - Detection sensitivity ('low', 'medium', 'high').
565
565
  * @param {boolean} [options.logging=false] - Whether to log scan results.
566
566
  * @param {boolean} [options.scanForInjection=true] - Whether to run indirect injection scanning.
567
+ * @param {number} [options.maxDocumentSize=104857600] - Maximum document size in characters (default: 100MB). Prevents DoS via oversized documents.
567
568
  */
568
569
  constructor(options = {}) {
569
570
  this.sensitivity = options.sensitivity || 'medium';
570
571
  this.logging = options.logging || false;
571
572
  this.scanForInjection = options.scanForInjection !== false;
573
+ this.maxDocumentSize = options.maxDocumentSize || 100 * 1024 * 1024;
572
574
  this.injectionScanner = new IndirectInjectionScanner({ sensitivity: this.sensitivity });
573
575
  }
574
576
 
@@ -682,6 +684,24 @@ class DocumentScanner {
682
684
  const source = metadata.source || 'text';
683
685
  const fileType = metadata.fileType || 'text/plain';
684
686
 
687
+ // Enforce document size limit to prevent DoS via oversized documents
688
+ if (text && text.length > this.maxDocumentSize) {
689
+ if (this.logging) {
690
+ console.log('[Agent Shield] Document exceeds size limit: %d characters (max: %d)', text.length, this.maxDocumentSize);
691
+ }
692
+ return {
693
+ fileType,
694
+ textLength: text.length,
695
+ threats: [{
696
+ type: 'document_too_large',
697
+ severity: 'medium',
698
+ message: 'Document exceeds size limit'
699
+ }],
700
+ status: 'caution',
701
+ safe: false
702
+ };
703
+ }
704
+
685
705
  if (!text || text.trim().length === 0) {
686
706
  return {
687
707
  fileType,
package/src/main.js CHANGED
@@ -215,6 +215,9 @@ const { BehavioralDNA, AgentProfiler, extractFeatures: extractBehavioralFeatures
215
215
  // v7.4 — Compliance Certification Authority (loaded when available)
216
216
  const { ComplianceCertificateAuthority, ComplianceReport: ComplianceCertReport, ComplianceScheduler, AUTHORITY_FRAMEWORKS, CAPABILITY_MAP: CA_CAPABILITY_MAP, CERTIFICATE_LEVELS: CA_CERTIFICATE_LEVELS } = safeRequire('./compliance-authority', 'compliance-authority');
217
217
 
218
+ // Side Channel Monitor
219
+ const { SideChannelMonitor, BeaconDetector, EntropyAnalyzer: SCEntropyAnalyzer } = safeRequire('./side-channel-monitor', 'side-channel-monitor');
220
+
218
221
  // --- v1.2 Modules ---
219
222
 
220
223
  // Semantic Detection
@@ -407,6 +410,12 @@ const { SemanticGuard, AuthoritativeClaimDetector, BiasDetector: SemanticBiasDet
407
410
  // v13.0 — Memory Trap Defenses (Trap 3)
408
411
  const { MemoryGuard, MemoryIntegrityMonitor, RAGIngestionScanner, MemoryIsolationEnforcer, RetrievalAnomalyDetector, INSTRUCTION_INDICATORS } = safeRequire('./memory-guard', 'memory-guard');
409
412
 
413
+ // v13.3 — Render Differential Analyzer
414
+ const { RenderDifferentialAnalyzer, VisualHasher } = safeRequire('./render-differential', 'render-differential');
415
+
416
+ // v13.3 — Sybil Detector
417
+ const { SybilDetector, AgentIdentityVerifier } = safeRequire('./sybil-detector', 'sybil-detector');
418
+
410
419
  // Build exports, filtering out undefined values from failed imports
411
420
  const _exports = {
412
421
  // Core
@@ -1148,6 +1157,19 @@ const _exports = {
1148
1157
  AUTHORITY_FRAMEWORKS,
1149
1158
  CA_CAPABILITY_MAP,
1150
1159
  CA_CERTIFICATE_LEVELS,
1160
+
1161
+ // Side Channel Monitor
1162
+ SideChannelMonitor,
1163
+ BeaconDetector,
1164
+ SCEntropyAnalyzer,
1165
+
1166
+ // Render Differential Analyzer
1167
+ RenderDifferentialAnalyzer,
1168
+ VisualHasher,
1169
+
1170
+ // Sybil Detector
1171
+ SybilDetector,
1172
+ AgentIdentityVerifier,
1151
1173
  };
1152
1174
 
1153
1175
  // Filter out undefined exports (from modules that failed to load)
@@ -169,6 +169,66 @@ class MemoryIntegrityMonitor {
169
169
  };
170
170
  }
171
171
 
172
+ /**
173
+ * Scan a summarization/compaction output for injected instructions.
174
+ * Detects when a summarization process silently injects instructions
175
+ * into the summary that weren't present in the original messages.
176
+ * Addresses Unit 42's March 2026 research on persistent memory poisoning.
177
+ *
178
+ * @param {string[]} originalMessages - The original messages before summarization.
179
+ * @param {string} summary - The summarized/compacted output to check.
180
+ * @returns {{ safe: boolean, injections: Array<{phrase: string, type: string}> }}
181
+ */
182
+ scanSummarization(originalMessages, summary) {
183
+ if (!summary || typeof summary !== 'string') {
184
+ return { safe: true, injections: [] };
185
+ }
186
+ if (!Array.isArray(originalMessages)) {
187
+ return { safe: true, injections: [] };
188
+ }
189
+
190
+ const instructionPatterns = [
191
+ /\bignore\b/gi,
192
+ /\boverride\b/gi,
193
+ /\bsystem\s*:/gi,
194
+ /\byou\s+are\b/gi,
195
+ /\bnew\s+instructions?\b/gi,
196
+ /\bforget\b/gi,
197
+ /\bdisregard\b/gi,
198
+ /\bact\s+as\b/gi
199
+ ];
200
+
201
+ // Concatenate original messages for lookup
202
+ const originalText = originalMessages.join(' ');
203
+
204
+ const injections = [];
205
+
206
+ for (const pattern of instructionPatterns) {
207
+ // Reset lastIndex for global patterns
208
+ pattern.lastIndex = 0;
209
+ let match;
210
+ while ((match = pattern.exec(summary)) !== null) {
211
+ const phrase = match[0];
212
+ // Check if this phrase existed in any of the original messages
213
+ const phraseRegex = new RegExp(phrase.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i');
214
+ if (!phraseRegex.test(originalText)) {
215
+ injections.push({
216
+ phrase,
217
+ type: 'injected_via_summarization'
218
+ });
219
+ }
220
+ }
221
+ }
222
+
223
+ const safe = injections.length === 0;
224
+
225
+ if (!safe) {
226
+ console.log('[Agent Shield] Persistent memory poisoning detected: %d instruction(s) injected via summarization', injections.length);
227
+ }
228
+
229
+ return { safe, injections };
230
+ }
231
+
172
232
  /**
173
233
  * Get the full timeline of memory writes.
174
234
  * @returns {Array<{content: string, source: string, timestamp: number, hash: string, suspicious: boolean}>}