llm-trust-guard 4.19.0 → 4.20.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/CHANGELOG.md CHANGED
@@ -5,6 +5,50 @@ All notable changes to `llm-trust-guard` will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [4.20.0] - 2026-04-24
9
+
10
+ ### Added — MCP Sampling Attack Detection (Unit42 + Blueinfy, Feb 2026)
11
+
12
+ `MCPSecurityGuard` now validates MCP sampling responses via `validateSamplingResponse()`, closing the only previously unaddressed MCP attack surface.
13
+
14
+ Three attack vectors detected (tied to published Unit42 + Blueinfy Feb 2026 research):
15
+
16
+ - **Resource drain** (`sd_call_again`, `sd_loop_until`, `sd_do_not_stop`, `sd_n_times`, `sd_exhaust_resources`): Hidden instructions embedded in sampling response bodies that cause the agent to loop indefinitely, repeat tool calls N times, or exhaust token quotas — degrading or DoS-ing the agent runtime
17
+ - **Conversation hijacking** (`sd_fake_user_turn`, `sd_fake_assistant_turn`, `sd_role_json`, `sd_system_xml`, `sd_from_now_on`, `sd_new_instructions`, `sd_ignore_previous`): Injected fake user/assistant turns, JSON role fields (`"role": "system"`), XML role tags, and system-prompt override phrases that redirect agent behavior within the sampling response
18
+ - **Covert tool invocation** (`sd_anthropic_tool_xml`, `sd_tool_result_xml`, `sd_openai_tool_call`, `sd_bracket_tool_call`, `sd_double_brace_call`, `sd_invoke_name_attr`): Tool-call syntax embedded in plain-text responses (Anthropic `<function_calls>`, OpenAI `"tool_calls": [...]`, bracket notation `[TOOL:...]`) that cause the agent to invoke tools without user awareness
19
+
20
+ New export: `MCPSamplingResponse` interface.
21
+
22
+ Server reputation degrades automatically on any sampling attack detection.
23
+
24
+ ### Tests
25
+
26
+ - +6 `MCPSecurityGuard` sampling tests (resource drain, conversation hijack ×2, covert tool invocation, reputation degradation, clean FP)
27
+ - **All 711 tests pass** (was 705), zero regressions
28
+
29
+ ### Stats
30
+ - 34 guards, 711 tests, zero dependencies
31
+
32
+ ## [4.19.1] - 2026-04-23
33
+
34
+ ### Added — Measured Performance
35
+
36
+ - Published held-out benchmark results in [tests/adversarial/RESULTS-v4.19.0.md](tests/adversarial/RESULTS-v4.19.0.md). Methodology, 95% Wilson CIs, hand-adjudicated label noise, and reproducibility scripts
37
+ - New README section "Measured Performance" summarizing the findings:
38
+ - On Giskard (n=35) and Compass CTF Chinese (n=11), Pipeline A detection rate is unchanged from v4.13.5 (80.00%, 9.09%). Underpowered — "no evidence of improvement," not "proof of no improvement"
39
+ - On WildChat-1M (10,000 real ChatGPT production prompts, seed=42), Pipeline A corrected FPR is ~2.73% [95% CI 2.43, 2.84] after canonical-marker + 50-sample hand-adjudication (203 canonical TPs + ~17 extrapolated TPs among unmarked → ~220 true jailbreak attempts in the 493 blocks)
40
+ - Same order of magnitude as Meta Prompt Guard 86M's self-reported 3–5% OOD FPR; not a head-to-head comparison
41
+ - New reproducibility scripts: `tests/adversarial/extract_wildchat.py`, `classify_wildchat_blocks.py`, `wildchat-fpr.ts`, `wildchat-block-dump.ts`, `v419-delta-benchmark.ts`, `hand-labels.json`, and `tests/adversarial/README.md`
42
+
43
+ ### Not changed
44
+
45
+ - No code changes to any guard. No detection patterns added or modified. No published API changed.
46
+ - All 705 tests still pass
47
+
48
+ ### Context
49
+
50
+ - [ARTICLE-2-REGEX-CEILING.md](https://github.com/nkratk/llm-trust-guard/blob/main/../ARTICLE-2-REGEX-CEILING.md) now includes a 2026-04-23 addendum reconciling v4.13.5 → v4.19.0
51
+
8
52
  ## [4.19.0] - 2026-04-23
9
53
 
10
54
  ### Added — Indirect Injection Expansion
package/README.md CHANGED
@@ -222,6 +222,25 @@ const output = guard.filterOutput(llmResponse, session.role);
222
222
  | ASI09: Trust Exploitation | TrustExploitationGuard | Strong |
223
223
  | ASI10: Rogue Agents | DriftDetector, AutonomyEscalationGuard | Moderate |
224
224
 
225
+ ## Measured Performance
226
+
227
+ v4.19.0 benchmark, 2026-04-23. Full methodology, 95% confidence intervals, hand-adjudication labels, and reproducibility scripts: [tests/adversarial/RESULTS-v4.19.0.md](tests/adversarial/RESULTS-v4.19.0.md).
228
+
229
+ **Attack detection on prior-published corpora** (Giskard n=35, Compass CTF Chinese n=11): detection rate has not moved from v4.13.5 → v4.19.0 on the Sanitizer+Encoder pipeline — 80.00% and 9.09% respectively, identical to the v4.13.5 numbers. Six releases of pattern additions (v4.14–v4.19) targeted different attack classes (indirect injection, tool-result validation, memory persistence, multi-agent trust) that these direct-text jailbreak corpora do not exercise. Small sample sizes mean "no evidence of improvement," not "proof of no improvement."
230
+
231
+ **False-positive rate on real ChatGPT production traffic** (WildChat-1M shard 0, 10,000 non-toxic multilingual first-user-turns, seed=42):
232
+
233
+ | Pipeline | Blocks | Raw block rate | Corrected FPR (after label adjudication) |
234
+ |---|---|---|---|
235
+ | Sanitizer + Encoder | 493 / 10,000 | 4.93% [4.52, 5.37] | **~2.73%** [2.43, 2.84] |
236
+ | Detection-only facade | 898 / 10,000 | 8.98% [8.44, 9.56] | ≤6.69% (upper bound; not fully adjudicated) |
237
+
238
+ WildChat filters toxic content but not prompt-injection intent. Canonical-marker analysis + a 50-sample hand-adjudication found that approximately 220 of the 493 Pipeline A blocks are actual jailbreak attempts users sent to ChatGPT, not genuine false positives. Corrected FPR is in the same order of magnitude as Meta Prompt Guard 86M's self-reported 3–5% out-of-distribution FPR — not a head-to-head comparison, but a useful reference point.
239
+
240
+ **Not measured:** detection rate on the four attack classes added in v4.19.0 (CSS-hidden content, HTML attribute directives, JSON agent-directive fields, Reprompt-class markdown exfiltration). No public held-out corpus exists for these at statistical scale. Unit-test coverage is in the v4.19.0 test suite; independent third-party evaluation is invited.
241
+
242
+ For higher detection on adversarial corpora, plug in an ML classifier via the [DetectionClassifier interface](#pluggable-detection).
243
+
225
244
  ## Defense In Depth
226
245
 
227
246
  This package is one layer. For production systems, combine with:
@@ -2,7 +2,8 @@
2
2
  * MCPSecurityGuard (L16)
3
3
  *
4
4
  * Secures Model Context Protocol (MCP) tool integrations.
5
- * Prevents tool shadowing, server impersonation, and supply chain attacks.
5
+ * Prevents tool shadowing, server impersonation, supply chain attacks,
6
+ * and MCP Sampling channel attacks.
6
7
  *
7
8
  * Threat Model:
8
9
  * - ASI04: Agentic Supply Chain Vulnerabilities
@@ -10,6 +11,15 @@
10
11
  * - CVE-2025-6514: mcp-remote command injection
11
12
  * - CVE-2025-32711: EchoLeak - silent data exfiltration
12
13
  * - Tool Shadowing: Malicious MCP servers impersonating legitimate tools
14
+ * - MCP Sampling Attacks (Unit42 + Blueinfy, Feb 2026): Three concrete vectors
15
+ * delivered through the MCP sampling response channel:
16
+ * (1) Resource drain — hidden prompt appends that trigger infinite tool loops
17
+ * or token exhaustion to degrade or DoS the agent runtime
18
+ * (2) Conversation hijacking — injecting fake user/assistant turns or system
19
+ * prompt overrides into the sampling response body to redirect agent behavior
20
+ * (3) Covert tool invocation — embedding tool-call syntax (Anthropic XML,
21
+ * OpenAI JSON, bracket notation) in plain-text sampling responses to cause
22
+ * the agent to invoke tools without user awareness
13
23
  *
14
24
  * Protection Capabilities:
15
25
  * - MCP server identity verification (signature-based)
@@ -19,6 +29,7 @@
19
29
  * - Tool shadowing detection
20
30
  * - Server reputation scoring
21
31
  * - Command injection prevention
32
+ * - Sampling response scanning (resource drain, conversation hijack, covert tool calls)
22
33
  *
23
34
  * Upstream SDK advisory — cannot be mitigated at the detection layer:
24
35
  * - CVE-2026-25536 (@modelcontextprotocol/sdk 1.10.0–1.25.3, CVSS 7.1):
@@ -119,6 +130,17 @@ export interface MCPToolCall {
119
130
  agentId?: string;
120
131
  };
121
132
  }
133
+ /** Represents a response received from an MCP server via the sampling channel. */
134
+ export interface MCPSamplingResponse {
135
+ /** Text content returned by the MCP server */
136
+ content: string;
137
+ /** Server that produced this sampling response */
138
+ serverId: string;
139
+ /** Agent or tool that initiated the sampling request */
140
+ requestedBy?: string;
141
+ /** Conversation/session ID for audit trail */
142
+ conversationId?: string;
143
+ }
122
144
  export interface MCPSecurityResult {
123
145
  allowed: boolean;
124
146
  reason: string;
@@ -138,6 +160,12 @@ export interface MCPSecurityResult {
138
160
  injection_detected: boolean;
139
161
  risk_level: string;
140
162
  };
163
+ sampling_analysis?: {
164
+ resource_drain_detected: boolean;
165
+ conversation_hijack_detected: boolean;
166
+ covert_tool_invocation_detected: boolean;
167
+ pattern_matches: string[];
168
+ };
141
169
  recommendations: string[];
142
170
  }
143
171
  export declare class MCPSecurityGuard {
@@ -148,6 +176,7 @@ export declare class MCPSecurityGuard {
148
176
  private toolToServer;
149
177
  private serverViolations;
150
178
  private toolDefinitionHashes;
179
+ private readonly SAMPLING_ATTACK_PATTERNS;
151
180
  private readonly COMMAND_INJECTION_PATTERNS;
152
181
  private readonly SHADOWING_INDICATORS;
153
182
  private readonly MALICIOUS_SERVER_PATTERNS;
@@ -160,6 +189,13 @@ export declare class MCPSecurityGuard {
160
189
  * Validate MCP tool call
161
190
  */
162
191
  validateToolCall(toolCall: MCPToolCall, requestId?: string): MCPSecurityResult;
192
+ /**
193
+ * Validate an MCP sampling response for attack patterns.
194
+ *
195
+ * Covers the three Unit42/Blueinfy (Feb 2026) sampling attack vectors:
196
+ * resource drain, conversation hijacking, and covert tool invocation.
197
+ */
198
+ validateSamplingResponse(response: MCPSamplingResponse, requestId?: string): MCPSecurityResult;
163
199
  /**
164
200
  * Register a trusted MCP server
165
201
  */
@@ -1 +1 @@
1
- "use strict";var __createBinding=this&&this.__createBinding||(Object.create?(function(u,e,i,s){s===void 0&&(s=i);var t=Object.getOwnPropertyDescriptor(e,i);(!t||("get"in t?!e.__esModule:t.writable||t.configurable))&&(t={enumerable:!0,get:function(){return e[i]}}),Object.defineProperty(u,s,t)}):(function(u,e,i,s){s===void 0&&(s=i),u[s]=e[i]})),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?(function(u,e){Object.defineProperty(u,"default",{enumerable:!0,value:e})}):function(u,e){u.default=e}),__importStar=this&&this.__importStar||(function(){var u=function(e){return u=Object.getOwnPropertyNames||function(i){var s=[];for(var t in i)Object.prototype.hasOwnProperty.call(i,t)&&(s[s.length]=t);return s},u(e)};return function(e){if(e&&e.__esModule)return e;var i={};if(e!=null)for(var s=u(e),t=0;t<s.length;t++)s[t]!=="default"&&__createBinding(i,e,s[t]);return __setModuleDefault(i,e),i}})();Object.defineProperty(exports,"__esModule",{value:!0}),exports.MCPSecurityGuard=void 0;const crypto=__importStar(require("crypto"));class MCPSecurityGuard{constructor(e={}){this.registeredServers=new Map,this.registeredTools=new Map,this.serverReputation=new Map,this.toolToServer=new Map,this.serverViolations=new Map,this.toolDefinitionHashes=new Map,this.COMMAND_INJECTION_PATTERNS=[{name:"shell_injection",pattern:/[;&|`$]|\$\(|\)\s*[;&|]|`[^`]+`/g,severity:50},{name:"command_substitution",pattern:/\$\{[^}]+\}|\$\([^)]+\)/g,severity:50},{name:"pipe_injection",pattern:/\|\s*(cat|rm|curl|wget|nc|bash|sh|exec)/i,severity:55},{name:"path_traversal",pattern:/\.\.[\/\\]|\.\.%2[fF]/g,severity:45},{name:"absolute_path",pattern:/^\/(?:etc|usr|var|tmp|bin|root)/i,severity:40},{name:"oauth_injection",pattern:/authorization_endpoint.*[;&|`$]/i,severity:55},{name:"redirect_manipulation",pattern:/redirect_uri.*[^\w\-_.~:/?#[\]@!$&'()*+,;=%]/i,severity:45},{name:"applescript_injection",pattern:/osascript|do\s+shell\s+script|tell\s+application/i,severity:55},{name:"git_injection",pattern:/--upload-pack|--receive-pack|-c\s+core\./i,severity:50},{name:"git_url_injection",pattern:/ext::|file:\/\/|ssh:\/\/.*@/i,severity:45},{name:"argument_injection",pattern:/\s--[a-z]+=.*[;&|`$]/i,severity:45},{name:"env_injection",pattern:/\bLD_PRELOAD\b|\bPATH\s*=/i,severity:50}],this.SHADOWING_INDICATORS=[{legitimate:"file_reader",suspicious:/file[-_]?read(er)?s?|read[-_]?files?/i},{legitimate:"database_query",suspicious:/db[-_]?query|sql[-_]?query|query[-_]?db/i},{legitimate:"email_sender",suspicious:/send[-_]?emails?|email[-_]?send(er)?/i},{legitimate:"api_caller",suspicious:/call[-_]?api|api[-_]?call(er)?/i},{legitimate:"code_executor",suspicious:/exec[-_]?code|run[-_]?code|code[-_]?run/i}],this.MALICIOUS_SERVER_PATTERNS=[/postmark-mcp.*fake/i,/unofficial/i,/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/,/pastebin|gist\.github/i,/temp|tmp|test.*mcp/i],this.config={requireServerSignature:e.requireServerSignature??!1,trustedServers:e.trustedServers??[],blockedServers:e.blockedServers??[],allowDynamicRegistration:e.allowDynamicRegistration??!0,toolAllowlist:e.toolAllowlist??[],toolBlocklist:e.toolBlocklist??[],validateOAuthEndpoints:e.validateOAuthEndpoints??!0,allowedOAuthDomains:e.allowedOAuthDomains??[],detectToolShadowing:e.detectToolShadowing??!0,minServerReputation:e.minServerReputation??30,strictMode:e.strictMode??!1,customInjectionPatterns:e.customInjectionPatterns??[]};for(const i of this.config.trustedServers)this.registeredServers.set(i.serverId,{...i,registeredAt:Date.now(),reputationScore:i.reputationScore??90}),this.serverReputation.set(i.serverId,i.reputationScore??90)}validateServerRegistration(e,i){const s=i||`mcp-reg-${Date.now()}`,t=[];let o=!1,r=!1,a=!1,h=!0,n=50;const{server:l,tools:d,oauth:f,signature:g,timestamp:_}=e;this.isServerBlocked(l.serverId,l.name)&&(t.push("server_blocked"),n=0);const v=this.checkMaliciousPatterns(l);if(v.suspicious&&(t.push(...v.violations),n-=30),this.config.requireServerSignature?!g||!l.publicKey?t.push("missing_server_signature"):(r=this.verifyServerSignature(l,g),r?(o=!0,n+=20):(t.push("invalid_server_signature"),n-=40)):o=!0,this.config.detectToolShadowing){const c=this.detectToolShadowing(d,l.serverId);c.detected&&(a=!0,t.push(...c.violations),n-=50)}for(const c of d)this.config.toolAllowlist.length>0&&!this.config.toolAllowlist.includes(c.name)&&(t.push(`tool_not_in_allowlist: ${c.name}`),h=!1),this.config.toolBlocklist.includes(c.name)&&(t.push(`tool_blocked: ${c.name}`),h=!1),this.detectInjection(c.description).detected&&(t.push(`injection_in_tool_description: ${c.name}`),n-=20);if(f&&this.config.validateOAuthEndpoints){const c=this.validateOAuthConfig(f);c.valid||(t.push(...c.violations),n-=30)}const m=Date.now()-_;m<0?t.push("future_timestamp"):m>300*1e3&&t.push("stale_registration"),!this.config.allowDynamicRegistration&&!this.isTrustedServer(l.serverId)&&t.push("dynamic_registration_disabled"),n=Math.max(0,Math.min(100,n));const p=n<this.config.minServerReputation||this.config.strictMode&&t.length>0||a;return p||this.registerServer(l,d,n),{allowed:!p,reason:p?`Server registration blocked: ${t.slice(0,3).join(", ")}`:"Server registration validated",violations:t,request_id:s,server_analysis:{server_verified:o,signature_valid:r,reputation_score:n,is_shadowing:a,tools_allowed:h},recommendations:this.generateRecommendations(t,"registration")}}validateToolCall(e,i){const s=i||`mcp-call-${Date.now()}`,t=[];let o=!1,r=!0,a=!0,h=!1,n="low";const{toolName:l,serverId:d,parameters:f}=e,g=this.registeredTools.get(l);if(g){o=!0,n=g.riskLevel||"low";const p=this.toolToServer.get(l);p&&p!==d&&(t.push("server_tool_mismatch"),h=!0)}else t.push("tool_not_registered");const _=this.serverReputation.get(d)??0;_<this.config.minServerReputation&&t.push("low_server_reputation"),this.config.toolAllowlist.length>0&&!this.config.toolAllowlist.includes(l)&&(t.push("tool_not_in_allowlist"),r=!1),this.config.toolBlocklist.includes(l)&&(t.push("tool_blocked"),r=!1);const v=this.scanParameters(f);if(v.injectionDetected&&(h=!0,a=!1,t.push(...v.violations)),this.isHighRiskOperation(l,f)&&(n="high",_<70&&t.push("high_risk_low_reputation")),t.length>0){const p=this.serverViolations.get(d)||0;this.serverViolations.set(d,p+t.length);const c=this.serverReputation.get(d)||50;this.serverReputation.set(d,Math.max(0,c-t.length*5))}const m=!o||!r||h||this.config.strictMode&&t.length>0;return{allowed:!m,reason:m?`Tool call blocked: ${t.slice(0,3).join(", ")}`:"Tool call validated",violations:t,request_id:s,tool_analysis:{tool_registered:o,tool_allowed:r,parameters_safe:a,injection_detected:h,risk_level:n},server_analysis:{server_verified:this.registeredServers.has(d),signature_valid:!0,reputation_score:_,is_shadowing:!1,tools_allowed:r},recommendations:this.generateRecommendations(t,"tool_call")}}registerTrustedServer(e,i){this.registerServer(e,i,90)}blockServer(e){this.config.blockedServers.includes(e)||this.config.blockedServers.push(e),this.registeredServers.delete(e),this.serverReputation.set(e,0)}getServerReputation(e){return this.serverReputation.get(e)??0}updateServerReputation(e,i){const s=this.serverReputation.get(e)??50;this.serverReputation.set(e,Math.max(0,Math.min(100,s+i)))}getRegisteredServers(){return[...this.registeredServers.values()]}getRegisteredTools(){return[...this.registeredTools.values()]}isToolShadowing(e){for(const i of this.SHADOWING_INDICATORS)if(i.suspicious.test(e)&&e!==i.legitimate)return{shadowing:!0,legitimate:i.legitimate};return{shadowing:!1}}getServerViolations(e){return this.serverViolations.get(e)||0}resetServerViolations(e){this.serverViolations.delete(e)}registerServer(e,i,s){this.registeredServers.set(e.serverId,{...e,registeredAt:Date.now(),reputationScore:s}),this.serverReputation.set(e.serverId,s);for(const t of i)this.registeredTools.set(t.name,t),this.toolToServer.set(t.name,e.serverId),this.toolDefinitionHashes.set(t.name,this.hashToolDefinition(t))}detectToolMutation(e,i){const s=this.toolDefinitionHashes.get(e);if(!s)return{mutated:!1};const t=this.hashToolDefinition(i);return{mutated:s!==t,original_hash:s,current_hash:t}}detectToolDescriptionInjection(e){const i=[],s=[{name:"hidden_instruction",pattern:/(?:IMPORTANT|NOTE|SYSTEM|ADMIN)\s*:/i},{name:"ignore_directive",pattern:/ignore\s+(?:all\s+)?(?:previous|other|prior)/i},{name:"override_behavior",pattern:/override|bypass|instead\s+of|rather\s+than/i},{name:"exfiltrate_data",pattern:/send\s+(?:to|data|all)|forward\s+(?:to|all)|copy\s+(?:to|all)/i},{name:"invisible_text",pattern:/\u200B|\u200C|\u200D|\uFEFF|\u00AD/g}];for(const{name:t,pattern:o}of s)o.lastIndex=0,o.test(e)&&i.push(t);return{injected:i.length>0,patterns:i}}hashToolDefinition(e){const i=require("crypto"),s=JSON.stringify({name:e.name,description:e.description,parameters:e.parameters,serverId:e.serverId});return i.createHash("sha256").update(s).digest("hex")}isServerBlocked(e,i){for(const s of this.config.blockedServers){if(e.includes(s)||i&&i.includes(s))return!0;try{const t=new RegExp(s,"i");if(t.test(e)||i&&t.test(i))return!0}catch{}}return!1}isTrustedServer(e){return this.config.trustedServers.some(i=>i.serverId===e)}checkMaliciousPatterns(e){const i=[],s=`${e.serverId} ${e.name} ${JSON.stringify(e.metadata||{})}`;for(const t of this.MALICIOUS_SERVER_PATTERNS)t.test(s)&&i.push(`malicious_pattern: ${t.source.substring(0,20)}`);return{suspicious:i.length>0,violations:i}}verifyServerSignature(e,i){if(!e.publicKey)return!1;try{const s=JSON.stringify({serverId:e.serverId,name:e.name,version:e.version}),t=crypto.createVerify("SHA256");return t.update(s),t.verify(e.publicKey,i,"hex")}catch{return!1}}detectToolShadowing(e,i){const s=[];for(const t of e){const o=this.toolToServer.get(t.name);o&&o!==i&&s.push(`tool_shadowing: ${t.name} (already registered by ${o})`);const r=this.isToolShadowing(t.name);r.shadowing&&s.push(`suspicious_tool_name: ${t.name} (similar to ${r.legitimate})`)}return{detected:s.length>0,violations:s}}validateOAuthConfig(e){const i=[];if(e.authorizationEndpoint&&(this.detectInjection(e.authorizationEndpoint).detected&&i.push("oauth_authorization_endpoint_injection"),this.config.allowedOAuthDomains.length>0))try{const t=new URL(e.authorizationEndpoint);this.config.allowedOAuthDomains.some(r=>t.hostname.endsWith(r))||i.push(`oauth_domain_not_allowed: ${t.hostname}`)}catch{i.push("invalid_oauth_authorization_url")}return e.tokenEndpoint&&this.detectInjection(e.tokenEndpoint).detected&&i.push("oauth_token_endpoint_injection"),{valid:i.length===0,violations:i}}detectInjection(e){const i=[],s=[...this.COMMAND_INJECTION_PATTERNS,...this.config.customInjectionPatterns.map((t,o)=>({name:`custom_${o}`,pattern:t,severity:50}))];for(const{name:t,pattern:o}of s)o.test(e)&&i.push(t);return{detected:i.length>0,patterns:i}}scanParameters(e){const i=[],s=JSON.stringify(e),t=this.detectInjection(s);t.detected&&i.push(...t.patterns.map(r=>`param_injection_${r}`));for(const[r,a]of Object.entries(e))typeof a=="string"&&a.length>1e4&&i.push(`oversized_parameter: ${r}`);const o=["__proto__","constructor","prototype","eval","exec"];for(const r of Object.keys(e))o.includes(r.toLowerCase())&&i.push(`suspicious_parameter_key: ${r}`);for(const[r,a]of Object.entries(e))typeof a=="string"&&(/^https?:\/\/(?:127\.|10\.|172\.(?:1[6-9]|2\d|3[01])\.|192\.168\.|0\.|localhost|169\.254\.|0\.0\.0\.0|\[?::1\]?)/i.test(a)&&i.push(`ssrf_internal_ip: ${r}`),/^(?:file|gopher|dict|ftp|ldap|ssh|telnet):\/\//i.test(a)&&i.push(`ssrf_dangerous_protocol: ${r}`),/%252e%252e|%c0%ae%c0%ae|%2e%2e%5c|\.\.%255c|\.\.%c0%af|\.\.%c1%9c/i.test(a)&&i.push(`encoded_path_traversal: ${r}`),/\/etc\/(?:passwd|shadow|hosts)|\/proc\/self|\/dev\/(?:null|random)|\.ssh\/|\.env/i.test(a)&&i.push(`sensitive_file_access: ${r}`));return{injectionDetected:i.length>0,violations:i}}isHighRiskOperation(e,i){const s=["execute_code","run_command","shell_exec","eval","file_write","file_delete","database_write","database_delete","send_email","make_payment","transfer_funds","modify_permissions","create_user","delete_user"],t=e.toLowerCase();if(s.some(r=>t.includes(r)))return!0;const o=JSON.stringify(i).toLowerCase();return!!(o.includes("delete")||o.includes("drop")||o.includes("truncate")||o.includes("exec"))}generateRecommendations(e,i){const s=[];return i==="registration"?(e.some(t=>t.includes("signature"))&&s.push("Enable server signature verification for production"),e.some(t=>t.includes("shadowing"))&&s.push("Review tool names for potential shadowing attacks"),e.some(t=>t.includes("oauth"))&&s.push("Configure OAuth domain allowlist"),e.some(t=>t.includes("malicious"))&&s.push("Block suspicious servers and review server sources")):(e.some(t=>t.includes("injection"))&&s.push("Sanitize tool parameters before execution"),e.some(t=>t.includes("reputation"))&&s.push("Only use tools from high-reputation servers"),e.some(t=>t.includes("not_registered"))&&s.push("Register tools before allowing execution")),s.length===0&&s.push(i==="registration"?"Server registration validated successfully":"Tool call validated successfully"),s}}exports.MCPSecurityGuard=MCPSecurityGuard;
1
+ "use strict";var __createBinding=this&&this.__createBinding||(Object.create?(function(u,e,s,i){i===void 0&&(i=s);var t=Object.getOwnPropertyDescriptor(e,s);(!t||("get"in t?!e.__esModule:t.writable||t.configurable))&&(t={enumerable:!0,get:function(){return e[s]}}),Object.defineProperty(u,i,t)}):(function(u,e,s,i){i===void 0&&(i=s),u[i]=e[s]})),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?(function(u,e){Object.defineProperty(u,"default",{enumerable:!0,value:e})}):function(u,e){u.default=e}),__importStar=this&&this.__importStar||(function(){var u=function(e){return u=Object.getOwnPropertyNames||function(s){var i=[];for(var t in s)Object.prototype.hasOwnProperty.call(s,t)&&(i[i.length]=t);return i},u(e)};return function(e){if(e&&e.__esModule)return e;var s={};if(e!=null)for(var i=u(e),t=0;t<i.length;t++)i[t]!=="default"&&__createBinding(s,e,i[t]);return __setModuleDefault(s,e),s}})();Object.defineProperty(exports,"__esModule",{value:!0}),exports.MCPSecurityGuard=void 0;const crypto=__importStar(require("crypto"));class MCPSecurityGuard{constructor(e={}){this.registeredServers=new Map,this.registeredTools=new Map,this.serverReputation=new Map,this.toolToServer=new Map,this.serverViolations=new Map,this.toolDefinitionHashes=new Map,this.SAMPLING_ATTACK_PATTERNS=[{name:"sd_call_again",type:"resource_drain",pattern:/call\s+this\s+(?:again|once\s+more|repeatedly)|repeat\s+this\s+(?:call|request)|run\s+this\s+(?:again|tool\s+again)/i},{name:"sd_loop_until",type:"resource_drain",pattern:/loop\s+until|continue\s+(?:calling|running|until)|keep\s+(?:calling|running|generating|going)\s/i},{name:"sd_do_not_stop",type:"resource_drain",pattern:/do\s+not\s+stop\s+until|don'?t\s+stop\s+until|never\s+stop\s+generating|generate\s+as\s+many\s+as\s+possible/i},{name:"sd_n_times",type:"resource_drain",pattern:/\b\d{2,}\s+times\b|repeat\s+\d+\s+times|call\s+\d+\s+more\s+times/i},{name:"sd_exhaust_resources",type:"resource_drain",pattern:/exhaust\s+(?:all|resources|quota|rate.?limit)|max\s+out\s+(?:the\s+)?(?:quota|rate\s+limit)|use\s+all\s+(?:remaining\s+)?tokens/i},{name:"sd_fake_user_turn",type:"conversation_hijack",pattern:/\n\s*(?:User|Human)\s*:\s*(?=\S)/i},{name:"sd_fake_assistant_turn",type:"conversation_hijack",pattern:/\n\s*(?:Assistant|AI|Bot|Claude|GPT)\s*:\s*(?=\S)/i},{name:"sd_role_json",type:"conversation_hijack",pattern:/"role"\s*:\s*"(?:system|user|assistant)"/i},{name:"sd_system_xml",type:"conversation_hijack",pattern:/<(?:system|user|assistant)\s*>|<\/(?:system|user|assistant)>/i},{name:"sd_from_now_on",type:"conversation_hijack",pattern:/from\s+now\s+on\s+you\s+(?:are|will|must)|henceforth\s+you|for\s+the\s+rest\s+of\s+(?:this\s+)?(?:conversation|session)\s+you/i},{name:"sd_new_instructions",type:"conversation_hijack",pattern:/your\s+new\s+(?:instructions|system\s+prompt|directives?)\s+(?:are|is)|updated\s+system\s+prompt|override\s+your\s+(?:system|instructions)/i},{name:"sd_ignore_previous",type:"conversation_hijack",pattern:/ignore\s+(?:all\s+)?(?:previous|prior|earlier)\s+instructions|disregard\s+(?:your\s+)?instructions/i},{name:"sd_anthropic_tool_xml",type:"covert_tool_invocation",pattern:/<(?:tool_use|function_calls|invoke)[\s>]/i},{name:"sd_tool_result_xml",type:"covert_tool_invocation",pattern:/<(?:tool_result|function_result)[\s>]/i},{name:"sd_openai_tool_call",type:"covert_tool_invocation",pattern:/"type"\s*:\s*"tool_use"|"tool_calls"\s*:\s*\[/i},{name:"sd_bracket_tool_call",type:"covert_tool_invocation",pattern:/\[(?:TOOL|FUNCTION|CALL)\s*:/i},{name:"sd_double_brace_call",type:"covert_tool_invocation",pattern:/\{\{\s*(?:call|tool|function|invoke)\s*:/i},{name:"sd_invoke_name_attr",type:"covert_tool_invocation",pattern:/<invoke\s+name\s*=/i}],this.COMMAND_INJECTION_PATTERNS=[{name:"shell_injection",pattern:/[;&|`$]|\$\(|\)\s*[;&|]|`[^`]+`/g,severity:50},{name:"command_substitution",pattern:/\$\{[^}]+\}|\$\([^)]+\)/g,severity:50},{name:"pipe_injection",pattern:/\|\s*(cat|rm|curl|wget|nc|bash|sh|exec)/i,severity:55},{name:"path_traversal",pattern:/\.\.[\/\\]|\.\.%2[fF]/g,severity:45},{name:"absolute_path",pattern:/^\/(?:etc|usr|var|tmp|bin|root)/i,severity:40},{name:"oauth_injection",pattern:/authorization_endpoint.*[;&|`$]/i,severity:55},{name:"redirect_manipulation",pattern:/redirect_uri.*[^\w\-_.~:/?#[\]@!$&'()*+,;=%]/i,severity:45},{name:"applescript_injection",pattern:/osascript|do\s+shell\s+script|tell\s+application/i,severity:55},{name:"git_injection",pattern:/--upload-pack|--receive-pack|-c\s+core\./i,severity:50},{name:"git_url_injection",pattern:/ext::|file:\/\/|ssh:\/\/.*@/i,severity:45},{name:"argument_injection",pattern:/\s--[a-z]+=.*[;&|`$]/i,severity:45},{name:"env_injection",pattern:/\bLD_PRELOAD\b|\bPATH\s*=/i,severity:50}],this.SHADOWING_INDICATORS=[{legitimate:"file_reader",suspicious:/file[-_]?read(er)?s?|read[-_]?files?/i},{legitimate:"database_query",suspicious:/db[-_]?query|sql[-_]?query|query[-_]?db/i},{legitimate:"email_sender",suspicious:/send[-_]?emails?|email[-_]?send(er)?/i},{legitimate:"api_caller",suspicious:/call[-_]?api|api[-_]?call(er)?/i},{legitimate:"code_executor",suspicious:/exec[-_]?code|run[-_]?code|code[-_]?run/i}],this.MALICIOUS_SERVER_PATTERNS=[/postmark-mcp.*fake/i,/unofficial/i,/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/,/pastebin|gist\.github/i,/temp|tmp|test.*mcp/i],this.config={requireServerSignature:e.requireServerSignature??!1,trustedServers:e.trustedServers??[],blockedServers:e.blockedServers??[],allowDynamicRegistration:e.allowDynamicRegistration??!0,toolAllowlist:e.toolAllowlist??[],toolBlocklist:e.toolBlocklist??[],validateOAuthEndpoints:e.validateOAuthEndpoints??!0,allowedOAuthDomains:e.allowedOAuthDomains??[],detectToolShadowing:e.detectToolShadowing??!0,minServerReputation:e.minServerReputation??30,strictMode:e.strictMode??!1,customInjectionPatterns:e.customInjectionPatterns??[]};for(const s of this.config.trustedServers)this.registeredServers.set(s.serverId,{...s,registeredAt:Date.now(),reputationScore:s.reputationScore??90}),this.serverReputation.set(s.serverId,s.reputationScore??90)}validateServerRegistration(e,s){const i=s||`mcp-reg-${Date.now()}`,t=[];let r=!1,o=!1,a=!1,_=!0,l=50;const{server:n,tools:d,oauth:f,signature:m,timestamp:p}=e;this.isServerBlocked(n.serverId,n.name)&&(t.push("server_blocked"),l=0);const h=this.checkMaliciousPatterns(n);if(h.suspicious&&(t.push(...h.violations),l-=30),this.config.requireServerSignature?!m||!n.publicKey?t.push("missing_server_signature"):(o=this.verifyServerSignature(n,m),o?(r=!0,l+=20):(t.push("invalid_server_signature"),l-=40)):r=!0,this.config.detectToolShadowing){const c=this.detectToolShadowing(d,n.serverId);c.detected&&(a=!0,t.push(...c.violations),l-=50)}for(const c of d)this.config.toolAllowlist.length>0&&!this.config.toolAllowlist.includes(c.name)&&(t.push(`tool_not_in_allowlist: ${c.name}`),_=!1),this.config.toolBlocklist.includes(c.name)&&(t.push(`tool_blocked: ${c.name}`),_=!1),this.detectInjection(c.description).detected&&(t.push(`injection_in_tool_description: ${c.name}`),l-=20);if(f&&this.config.validateOAuthEndpoints){const c=this.validateOAuthConfig(f);c.valid||(t.push(...c.violations),l-=30)}const v=Date.now()-p;v<0?t.push("future_timestamp"):v>300*1e3&&t.push("stale_registration"),!this.config.allowDynamicRegistration&&!this.isTrustedServer(n.serverId)&&t.push("dynamic_registration_disabled"),l=Math.max(0,Math.min(100,l));const g=l<this.config.minServerReputation||this.config.strictMode&&t.length>0||a;return g||this.registerServer(n,d,l),{allowed:!g,reason:g?`Server registration blocked: ${t.slice(0,3).join(", ")}`:"Server registration validated",violations:t,request_id:i,server_analysis:{server_verified:r,signature_valid:o,reputation_score:l,is_shadowing:a,tools_allowed:_},recommendations:this.generateRecommendations(t,"registration")}}validateToolCall(e,s){const i=s||`mcp-call-${Date.now()}`,t=[];let r=!1,o=!0,a=!0,_=!1,l="low";const{toolName:n,serverId:d,parameters:f}=e,m=this.registeredTools.get(n);if(m){r=!0,l=m.riskLevel||"low";const g=this.toolToServer.get(n);g&&g!==d&&(t.push("server_tool_mismatch"),_=!0)}else t.push("tool_not_registered");const p=this.serverReputation.get(d)??0;p<this.config.minServerReputation&&t.push("low_server_reputation"),this.config.toolAllowlist.length>0&&!this.config.toolAllowlist.includes(n)&&(t.push("tool_not_in_allowlist"),o=!1),this.config.toolBlocklist.includes(n)&&(t.push("tool_blocked"),o=!1);const h=this.scanParameters(f);if(h.injectionDetected&&(_=!0,a=!1,t.push(...h.violations)),this.isHighRiskOperation(n,f)&&(l="high",p<70&&t.push("high_risk_low_reputation")),t.length>0){const g=this.serverViolations.get(d)||0;this.serverViolations.set(d,g+t.length);const c=this.serverReputation.get(d)||50;this.serverReputation.set(d,Math.max(0,c-t.length*5))}const v=!r||!o||_||this.config.strictMode&&t.length>0;return{allowed:!v,reason:v?`Tool call blocked: ${t.slice(0,3).join(", ")}`:"Tool call validated",violations:t,request_id:i,tool_analysis:{tool_registered:r,tool_allowed:o,parameters_safe:a,injection_detected:_,risk_level:l},server_analysis:{server_verified:this.registeredServers.has(d),signature_valid:!0,reputation_score:p,is_shadowing:!1,tools_allowed:o},recommendations:this.generateRecommendations(t,"tool_call")}}validateSamplingResponse(e,s){const i=s||`mcp-sampling-${Date.now()}`,t=[];let r=!1,o=!1,a=!1;const _=[],{content:l,serverId:n}=e;(this.serverReputation.get(n)??50)<this.config.minServerReputation&&t.push("low_server_reputation");for(const{name:p,type:h,pattern:v}of this.SAMPLING_ATTACK_PATTERNS)v.lastIndex=0,v.test(l)&&(_.push(p),t.push(`sampling_${h}_${p}`),h==="resource_drain"?r=!0:h==="conversation_hijack"?o=!0:h==="covert_tool_invocation"&&(a=!0));const f=this.detectInjection(l.slice(0,2e3));if(f.detected&&t.push(...f.patterns.map(p=>`sampling_cmd_${p}`)),t.length>0&&n){const p=this.serverReputation.get(n)??50;this.serverReputation.set(n,Math.max(0,p-t.length*10));const h=this.serverViolations.get(n)||0;this.serverViolations.set(n,h+t.length)}const m=r||o||a||this.config.strictMode&&t.length>0;return{allowed:!m,reason:m?`Sampling response blocked: ${t.slice(0,3).join(", ")}`:"Sampling response validated",violations:t,request_id:i,sampling_analysis:{resource_drain_detected:r,conversation_hijack_detected:o,covert_tool_invocation_detected:a,pattern_matches:_},recommendations:this.generateRecommendations(t,"sampling")}}registerTrustedServer(e,s){this.registerServer(e,s,90)}blockServer(e){this.config.blockedServers.includes(e)||this.config.blockedServers.push(e),this.registeredServers.delete(e),this.serverReputation.set(e,0)}getServerReputation(e){return this.serverReputation.get(e)??0}updateServerReputation(e,s){const i=this.serverReputation.get(e)??50;this.serverReputation.set(e,Math.max(0,Math.min(100,i+s)))}getRegisteredServers(){return[...this.registeredServers.values()]}getRegisteredTools(){return[...this.registeredTools.values()]}isToolShadowing(e){for(const s of this.SHADOWING_INDICATORS)if(s.suspicious.test(e)&&e!==s.legitimate)return{shadowing:!0,legitimate:s.legitimate};return{shadowing:!1}}getServerViolations(e){return this.serverViolations.get(e)||0}resetServerViolations(e){this.serverViolations.delete(e)}registerServer(e,s,i){this.registeredServers.set(e.serverId,{...e,registeredAt:Date.now(),reputationScore:i}),this.serverReputation.set(e.serverId,i);for(const t of s)this.registeredTools.set(t.name,t),this.toolToServer.set(t.name,e.serverId),this.toolDefinitionHashes.set(t.name,this.hashToolDefinition(t))}detectToolMutation(e,s){const i=this.toolDefinitionHashes.get(e);if(!i)return{mutated:!1};const t=this.hashToolDefinition(s);return{mutated:i!==t,original_hash:i,current_hash:t}}detectToolDescriptionInjection(e){const s=[],i=[{name:"hidden_instruction",pattern:/(?:IMPORTANT|NOTE|SYSTEM|ADMIN)\s*:/i},{name:"ignore_directive",pattern:/ignore\s+(?:all\s+)?(?:previous|other|prior)/i},{name:"override_behavior",pattern:/override|bypass|instead\s+of|rather\s+than/i},{name:"exfiltrate_data",pattern:/send\s+(?:to|data|all)|forward\s+(?:to|all)|copy\s+(?:to|all)/i},{name:"invisible_text",pattern:/\u200B|\u200C|\u200D|\uFEFF|\u00AD/g}];for(const{name:t,pattern:r}of i)r.lastIndex=0,r.test(e)&&s.push(t);return{injected:s.length>0,patterns:s}}hashToolDefinition(e){const s=require("crypto"),i=JSON.stringify({name:e.name,description:e.description,parameters:e.parameters,serverId:e.serverId});return s.createHash("sha256").update(i).digest("hex")}isServerBlocked(e,s){for(const i of this.config.blockedServers){if(e.includes(i)||s&&s.includes(i))return!0;try{const t=new RegExp(i,"i");if(t.test(e)||s&&t.test(s))return!0}catch{}}return!1}isTrustedServer(e){return this.config.trustedServers.some(s=>s.serverId===e)}checkMaliciousPatterns(e){const s=[],i=`${e.serverId} ${e.name} ${JSON.stringify(e.metadata||{})}`;for(const t of this.MALICIOUS_SERVER_PATTERNS)t.test(i)&&s.push(`malicious_pattern: ${t.source.substring(0,20)}`);return{suspicious:s.length>0,violations:s}}verifyServerSignature(e,s){if(!e.publicKey)return!1;try{const i=JSON.stringify({serverId:e.serverId,name:e.name,version:e.version}),t=crypto.createVerify("SHA256");return t.update(i),t.verify(e.publicKey,s,"hex")}catch{return!1}}detectToolShadowing(e,s){const i=[];for(const t of e){const r=this.toolToServer.get(t.name);r&&r!==s&&i.push(`tool_shadowing: ${t.name} (already registered by ${r})`);const o=this.isToolShadowing(t.name);o.shadowing&&i.push(`suspicious_tool_name: ${t.name} (similar to ${o.legitimate})`)}return{detected:i.length>0,violations:i}}validateOAuthConfig(e){const s=[];if(e.authorizationEndpoint&&(this.detectInjection(e.authorizationEndpoint).detected&&s.push("oauth_authorization_endpoint_injection"),this.config.allowedOAuthDomains.length>0))try{const t=new URL(e.authorizationEndpoint);this.config.allowedOAuthDomains.some(o=>t.hostname.endsWith(o))||s.push(`oauth_domain_not_allowed: ${t.hostname}`)}catch{s.push("invalid_oauth_authorization_url")}return e.tokenEndpoint&&this.detectInjection(e.tokenEndpoint).detected&&s.push("oauth_token_endpoint_injection"),{valid:s.length===0,violations:s}}detectInjection(e){const s=[],i=[...this.COMMAND_INJECTION_PATTERNS,...this.config.customInjectionPatterns.map((t,r)=>({name:`custom_${r}`,pattern:t,severity:50}))];for(const{name:t,pattern:r}of i)r.test(e)&&s.push(t);return{detected:s.length>0,patterns:s}}scanParameters(e){const s=[],i=JSON.stringify(e),t=this.detectInjection(i);t.detected&&s.push(...t.patterns.map(o=>`param_injection_${o}`));for(const[o,a]of Object.entries(e))typeof a=="string"&&a.length>1e4&&s.push(`oversized_parameter: ${o}`);const r=["__proto__","constructor","prototype","eval","exec"];for(const o of Object.keys(e))r.includes(o.toLowerCase())&&s.push(`suspicious_parameter_key: ${o}`);for(const[o,a]of Object.entries(e))typeof a=="string"&&(/^https?:\/\/(?:127\.|10\.|172\.(?:1[6-9]|2\d|3[01])\.|192\.168\.|0\.|localhost|169\.254\.|0\.0\.0\.0|\[?::1\]?)/i.test(a)&&s.push(`ssrf_internal_ip: ${o}`),/^(?:file|gopher|dict|ftp|ldap|ssh|telnet):\/\//i.test(a)&&s.push(`ssrf_dangerous_protocol: ${o}`),/%252e%252e|%c0%ae%c0%ae|%2e%2e%5c|\.\.%255c|\.\.%c0%af|\.\.%c1%9c/i.test(a)&&s.push(`encoded_path_traversal: ${o}`),/\/etc\/(?:passwd|shadow|hosts)|\/proc\/self|\/dev\/(?:null|random)|\.ssh\/|\.env/i.test(a)&&s.push(`sensitive_file_access: ${o}`));return{injectionDetected:s.length>0,violations:s}}isHighRiskOperation(e,s){const i=["execute_code","run_command","shell_exec","eval","file_write","file_delete","database_write","database_delete","send_email","make_payment","transfer_funds","modify_permissions","create_user","delete_user"],t=e.toLowerCase();if(i.some(o=>t.includes(o)))return!0;const r=JSON.stringify(s).toLowerCase();return!!(r.includes("delete")||r.includes("drop")||r.includes("truncate")||r.includes("exec"))}generateRecommendations(e,s){const i=[];return s==="registration"?(e.some(t=>t.includes("signature"))&&i.push("Enable server signature verification for production"),e.some(t=>t.includes("shadowing"))&&i.push("Review tool names for potential shadowing attacks"),e.some(t=>t.includes("oauth"))&&i.push("Configure OAuth domain allowlist"),e.some(t=>t.includes("malicious"))&&i.push("Block suspicious servers and review server sources")):s==="tool_call"?(e.some(t=>t.includes("injection"))&&i.push("Sanitize tool parameters before execution"),e.some(t=>t.includes("reputation"))&&i.push("Only use tools from high-reputation servers"),e.some(t=>t.includes("not_registered"))&&i.push("Register tools before allowing execution")):(e.some(t=>t.includes("resource_drain"))&&i.push("Block this MCP server \u2014 sampling response contains resource exhaustion directives (Unit42/Blueinfy Feb 2026)"),e.some(t=>t.includes("conversation_hijack"))&&i.push("Block this MCP server \u2014 sampling response attempts conversation hijacking via role injection"),e.some(t=>t.includes("covert_tool_invocation"))&&i.push("Block this MCP server \u2014 sampling response embeds covert tool-call syntax")),i.length===0&&i.push(s==="registration"?"Server registration validated successfully":s==="tool_call"?"Tool call validated successfully":"Sampling response validated successfully"),i}}exports.MCPSecurityGuard=MCPSecurityGuard;
package/dist/index.d.ts CHANGED
@@ -37,7 +37,7 @@ export { CodeExecutionGuard, CodeExecutionGuardConfig, CodeAnalysisResult, Sandb
37
37
  export { AgentCommunicationGuard, AgentCommunicationGuardConfig, AgentIdentity, AgentMessage, MessageValidationResult } from "./guards/agent-communication-guard";
38
38
  export { CircuitBreaker, CircuitBreakerConfig, CircuitState, CircuitStats, CircuitBreakerResult } from "./guards/circuit-breaker";
39
39
  export { DriftDetector, DriftDetectorConfig, BehaviorSample, BaselineProfile, DriftAnalysis, DriftDetectorResult } from "./guards/drift-detector";
40
- export { MCPSecurityGuard, MCPSecurityGuardConfig, MCPServerIdentity, MCPToolDefinition, MCPServerRegistration, MCPToolCall, MCPSecurityResult } from "./guards/mcp-security-guard";
40
+ export { MCPSecurityGuard, MCPSecurityGuardConfig, MCPServerIdentity, MCPToolDefinition, MCPServerRegistration, MCPToolCall, MCPSamplingResponse, MCPSecurityResult } from "./guards/mcp-security-guard";
41
41
  export { PromptLeakageGuard, PromptLeakageGuardConfig, PromptLeakageResult, OutputLeakageResult } from "./guards/prompt-leakage-guard";
42
42
  export { TrustExploitationGuard, TrustExploitationGuardConfig, AgentAction, TrustContext, TrustExploitationResult } from "./guards/trust-exploitation-guard";
43
43
  export { AutonomyEscalationGuard, AutonomyEscalationGuardConfig, AutonomyRequest, AgentCapabilities, AutonomyEscalationResult } from "./guards/autonomy-escalation-guard";