llm-trust-guard 4.19.1 → 4.20.1

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,43 @@ 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.1] - 2026-04-24
9
+
10
+ ### Changed — Documentation accuracy
11
+
12
+ - **README**: Removed "31 → 34 security guards" inconsistency (was contradicting the All 34 Guards table and `package.json`)
13
+ - **README**: Removed unmeasured "<5ms latency" assertion from intro
14
+ - **README**: Removed unmeasured "~97% on curated benchmarks" framing from "What it catches well"
15
+ - **README**: Qualified the four "100% detection" claims (Policy Puppetry, Role-play, PAP, Multilingual) as "100% on unit tests" with a section preface explaining that these are unit-test rates, not corpus measurements. Broader corpus measurements live in [RESULTS-v4.19.0.md](tests/adversarial/RESULTS-v4.19.0.md)
16
+ - **README**: Added Homoglyph attacks bullet to "What it catches well" (parity with Python README; feature exists in `encoding-detector`, `prompt-leakage-guard`, `multimodal-guard`, `memory-guard`)
17
+ - **README**: Added v4.20.0 MCP Sampling detection note in Measured Performance preface; benchmark numbers apply unchanged because Sampling is orthogonal to the Sanitizer+Encoder pipelines benchmarked
18
+
19
+ No code changes. Same 711 tests pass.
20
+
21
+ ## [4.20.0] - 2026-04-24
22
+
23
+ ### Added — MCP Sampling Attack Detection (Unit42 + Blueinfy, Feb 2026)
24
+
25
+ `MCPSecurityGuard` now validates MCP sampling responses via `validateSamplingResponse()`, closing the only previously unaddressed MCP attack surface.
26
+
27
+ Three attack vectors detected (tied to published Unit42 + Blueinfy Feb 2026 research):
28
+
29
+ - **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
30
+ - **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
31
+ - **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
32
+
33
+ New export: `MCPSamplingResponse` interface.
34
+
35
+ Server reputation degrades automatically on any sampling attack detection.
36
+
37
+ ### Tests
38
+
39
+ - +6 `MCPSecurityGuard` sampling tests (resource drain, conversation hijack ×2, covert tool invocation, reputation degradation, clean FP)
40
+ - **All 711 tests pass** (was 705), zero regressions
41
+
42
+ ### Stats
43
+ - 34 guards, 711 tests, zero dependencies
44
+
8
45
  ## [4.19.1] - 2026-04-23
9
46
 
10
47
  ### Added — Measured Performance
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![npm version](https://img.shields.io/npm/v/llm-trust-guard.svg)](https://www.npmjs.com/package/llm-trust-guard)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
 
6
- **31 security guards for LLM-powered and agentic AI applications.** Zero dependencies. <5ms latency. Covers OWASP Top 10 for LLMs 2025, OWASP Agentic AI 2026, and MCP Security.
6
+ **34 security guards for LLM-powered and agentic AI applications.** Zero dependencies. Covers OWASP Top 10 for LLMs 2025, OWASP Agentic AI 2026, and MCP Security.
7
7
 
8
8
  Also available as a [Python package on PyPI](https://pypi.org/project/llm-trust-guard/) (`pip install llm-trust-guard`).
9
9
 
@@ -13,13 +13,17 @@ Also available as a [Python package on PyPI](https://pypi.org/project/llm-trust-
13
13
 
14
14
  This package is your **first line of defense** — like a WAF (Web Application Firewall) for LLM applications. It sits in the orchestration layer and catches known attack patterns before they reach the LLM and after the LLM responds.
15
15
 
16
- ### What it catches well (~97% on curated benchmarks)
16
+ ### What it catches well
17
+
18
+ Per-category detection rates below are measured against the package's curated unit-test suite (representative attack samples per category). On broader held-out corpora these rates are typically lower — see [tests/adversarial/RESULTS-v4.19.0.md](tests/adversarial/RESULTS-v4.19.0.md) for measured detection on attack corpora and [Known limitations](#what-it-catches-partially-50-80-detection) below.
19
+
17
20
  - Known prompt injection phrases (170+ patterns, 11 languages)
18
21
  - Encoding bypass attacks (9 formats: Base64, URL, Unicode, Hex, HTML, ROT13, Octal, Base32, mixed)
19
- - Policy Puppetry attacks (JSON/INI/XML/YAML-formatted injection) — 100% detection
20
- - Role-play/persona attacks (translator trick, academic pretext, emotional manipulation) — 100% detection
21
- - PAP/persuasion attacks (authority, urgency, emotional manipulation) — 100% detection
22
- - Multilingual injection (10 languages) — 100% detection
22
+ - Policy Puppetry attacks (JSON/INI/XML/YAML-formatted injection) — 100% on unit tests
23
+ - Role-play/persona attacks (translator trick, academic pretext, emotional manipulation) — 100% on unit tests
24
+ - PAP/persuasion attacks (authority, urgency, emotional manipulation) — 100% on unit tests
25
+ - Multilingual injection (10 languages) — 100% on unit tests
26
+ - Homoglyph attacks (Cyrillic/Greek character substitution) — normalized and detected
23
27
  - PII and secret leakage in outputs
24
28
  - Tool hallucination, RBAC bypass, multi-tenant violations
25
29
  - Tool result poisoning, context window stuffing
@@ -224,7 +228,7 @@ const output = guard.filterOutput(llmResponse, session.role);
224
228
 
225
229
  ## Measured Performance
226
230
 
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).
231
+ v4.19.0 benchmark, 2026-04-23. v4.20.0 added MCP Sampling attack detection (see [CHANGELOG.md](CHANGELOG.md)) — orthogonal to the Sanitizer+Encoder pipelines below, so numbers apply unchanged. 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
232
 
229
233
  **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
234
 
@@ -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";