/** * MCPSecurityGuard (L16) * * Secures Model Context Protocol (MCP) tool integrations. * Prevents tool shadowing, server impersonation, supply chain attacks, * and MCP Sampling channel attacks. * * Threat Model: * - ASI04: Agentic Supply Chain Vulnerabilities * - CVE-2025-68145, CVE-2025-68143, CVE-2025-68144: MCP RCE vulnerabilities * - CVE-2025-6514: mcp-remote command injection * - CVE-2025-32711: EchoLeak - silent data exfiltration * - Tool Shadowing: Malicious MCP servers impersonating legitimate tools * - MCP Sampling Attacks (Unit42 + Blueinfy, Feb 2026): Three concrete vectors * delivered through the MCP sampling response channel: * (1) Resource drain — hidden prompt appends that trigger infinite tool loops * or token exhaustion to degrade or DoS the agent runtime * (2) Conversation hijacking — injecting fake user/assistant turns or system * prompt overrides into the sampling response body to redirect agent behavior * (3) Covert tool invocation — embedding tool-call syntax (Anthropic XML, * OpenAI JSON, bracket notation) in plain-text sampling responses to cause * the agent to invoke tools without user awareness * * Protection Capabilities: * - MCP server identity verification (signature-based) * - Tool registration allowlist enforcement * - Dynamic tool registration monitoring * - OAuth endpoint validation * - Tool shadowing detection * - Server reputation scoring * - Command injection prevention * - Sampling response scanning (resource drain, conversation hijack, covert tool calls) * * Upstream SDK advisory — cannot be mitigated at the detection layer: * - CVE-2026-25536 (@modelcontextprotocol/sdk 1.10.0–1.25.3, CVSS 7.1): * Cross-client response data leak when a single McpServer/Server and * transport instance is reused across multiple client connections * (common in stateless StreamableHTTPServerTransport deployments). * Fix: upgrade @modelcontextprotocol/sdk to >=1.26.0. This guard cannot * prevent the leak — it is a server-library bug — but tool-response * session-binding violations caught here can surface related symptoms. */ export interface MCPSecurityGuardConfig { /** Require server signature verification */ requireServerSignature?: boolean; /** Trusted MCP servers */ trustedServers?: MCPServerIdentity[]; /** Blocked server patterns (domains, names) */ blockedServers?: string[]; /** Allow dynamic tool registration at runtime */ allowDynamicRegistration?: boolean; /** Tool name allowlist (if set, only these tools are allowed) */ toolAllowlist?: string[]; /** Tool name blocklist */ toolBlocklist?: string[]; /** Validate OAuth endpoints */ validateOAuthEndpoints?: boolean; /** Allowed OAuth domains */ allowedOAuthDomains?: string[]; /** Enable tool shadowing detection */ detectToolShadowing?: boolean; /** Minimum server reputation score (0-100) */ minServerReputation?: number; /** Enable strict mode (block on any violation) */ strictMode?: boolean; /** Custom command injection patterns */ customInjectionPatterns?: RegExp[]; /** * Detect full-schema poisoning (FSP): instructions hidden in parameter names, * enum/default values, required[] and other non-description schema fields, * scanned at registration time. (CyberArk "Poison Everywhere", 2025.) Default: true. */ detectSchemaPoisoning?: boolean; /** * Detect line-jumping: a tool description that injects instructions into * context at tools/list time — pre-invocation directives, secrecy phrases, * fake-compliance framing. (Trail of Bits, 2025.) Default: true. */ detectLineJumping?: boolean; /** * Scan the entire server registration object for exposed credential values: * AWS keys, GitHub PATs, Bearer tokens, Stripe keys, Slack tokens, Google API * keys. Addresses MCP credential aggregation risk (Astrix Security, 2025: * 48% of MCP servers store credentials in plaintext). Default: true. */ detectCredentialExposure?: boolean; } export interface MCPServerIdentity { /** Server unique identifier */ serverId: string; /** Server name/display name */ name: string; /** Server version */ version?: string; /** Public key for signature verification (hex encoded) */ publicKey?: string; /** Trusted domains this server can operate on */ trustedDomains?: string[]; /** Tools this server is allowed to provide */ allowedTools?: string[]; /** Server metadata */ metadata?: Record; /** Registration timestamp */ registeredAt?: number; /** Reputation score (0-100) */ reputationScore?: number; } export interface MCPToolDefinition { /** Tool name */ name: string; /** Tool description */ description: string; /** Server providing this tool */ serverId: string; /** Tool parameters schema */ parameters?: Record; /** Tool capabilities/permissions required */ capabilities?: string[]; /** Tool risk level */ riskLevel?: "low" | "medium" | "high" | "critical"; } export interface MCPServerRegistration { /** Server identity */ server: MCPServerIdentity; /** Tools provided by this server */ tools: MCPToolDefinition[]; /** OAuth configuration if applicable */ oauth?: { authorizationEndpoint?: string; tokenEndpoint?: string; scopes?: string[]; }; /** Server signature (HMAC of server identity) */ signature?: string; /** Registration timestamp */ timestamp: number; } export interface MCPToolCall { /** Tool name being called */ toolName: string; /** Server providing the tool */ serverId: string; /** Tool parameters */ parameters: Record; /** Request context */ context?: { sessionId?: string; userId?: string; agentId?: string; }; } /** Represents a response received from an MCP server via the sampling channel. */ export interface MCPSamplingResponse { /** Text content returned by the MCP server */ content: string; /** Server that produced this sampling response */ serverId: string; /** Agent or tool that initiated the sampling request */ requestedBy?: string; /** Conversation/session ID for audit trail */ conversationId?: string; } export interface MCPSecurityResult { allowed: boolean; reason: string; violations: string[]; request_id: string; server_analysis?: { server_verified: boolean; signature_valid: boolean; reputation_score: number; is_shadowing: boolean; tools_allowed: boolean; }; tool_analysis?: { tool_registered: boolean; tool_allowed: boolean; parameters_safe: boolean; injection_detected: boolean; risk_level: string; }; sampling_analysis?: { resource_drain_detected: boolean; conversation_hijack_detected: boolean; covert_tool_invocation_detected: boolean; pattern_matches: string[]; }; recommendations: string[]; } export declare class MCPSecurityGuard { private config; private registeredServers; private registeredTools; private serverReputation; private toolToServer; private serverViolations; private toolDefinitionHashes; private readonly SAMPLING_ATTACK_PATTERNS; private readonly COMMAND_INJECTION_PATTERNS; private readonly SHADOWING_INDICATORS; private readonly MALICIOUS_SERVER_PATTERNS; constructor(config?: MCPSecurityGuardConfig); /** * Validate MCP server registration */ validateServerRegistration(registration: MCPServerRegistration, requestId?: string): MCPSecurityResult; /** * Validate MCP tool call */ validateToolCall(toolCall: MCPToolCall, requestId?: string): MCPSecurityResult; /** * Validate an MCP sampling response for attack patterns. * * Covers the three Unit42/Blueinfy (Feb 2026) sampling attack vectors: * resource drain, conversation hijacking, and covert tool invocation. */ /** * Generate obfuscation-decoded variants of a string. * Each variant is returned alongside the original so existing pattern logic * can scan all forms without changes to individual pattern sets. */ private preprocessContent; validateSamplingResponse(response: MCPSamplingResponse, requestId?: string): MCPSecurityResult; /** * Register a trusted MCP server */ registerTrustedServer(server: MCPServerIdentity, tools: MCPToolDefinition[]): void; /** * Block an MCP server */ blockServer(serverIdOrPattern: string): void; /** * Get server reputation */ getServerReputation(serverId: string): number; /** * Update server reputation */ updateServerReputation(serverId: string, delta: number): void; /** * Get all registered servers */ getRegisteredServers(): MCPServerIdentity[]; /** * Get all registered tools */ getRegisteredTools(): MCPToolDefinition[]; /** * Check if a tool name is potentially shadowing another */ isToolShadowing(toolName: string): { shadowing: boolean; legitimate?: string; }; /** * Get violation count for a server */ getServerViolations(serverId: string): number; /** * Reset server violations */ resetServerViolations(serverId: string): void; private registerServer; /** * Check if a tool's definition has mutated since registration (rug pull detection). * CVE-2025-6514: malicious MCP servers mutate tool definitions after approval. */ detectToolMutation(toolName: string, currentDefinition: MCPToolDefinition): { mutated: boolean; original_hash?: string; current_hash?: string; }; /** * Scan a tool description for hidden prompt injection (tool poisoning). */ detectToolDescriptionInjection(description: string): { injected: boolean; patterns: string[]; }; private hashToolDefinition; private isServerBlocked; private isTrustedServer; private checkMaliciousPatterns; private verifyServerSignature; private detectToolShadowing; private validateOAuthConfig; private detectInjection; /** Line-jumping cues: instructions a description tries to inject pre-invocation */ private readonly LINE_JUMPING_PATTERNS; /** * Detect line-jumping: imperative / secrecy / fake-compliance cues embedded in * a tool description that take effect the moment the description is loaded. */ private detectLineJumping; /** * Detect full-schema poisoning: walk every non-description field of a tool's * parameter schema (key names, enum/default/const values, required[], nested * objects) for injected instructions or suspicious payloads. */ private detectSchemaPoisoning; private detectCredentialExposure; private scanParameters; private isHighRiskOperation; private generateRecommendations; }