MCP

MCP Security Best Practices

Comprehensive security guide for Model Context Protocol implementations. Learn how to protect your MCP servers, secure AI interactions, and implement defense-in-depth strategies.

Security First Approach

MCP servers represent a critical security boundary between AI systems and your infrastructure. They can execute sensitive commands and access protected resources. Always implement security controls appropriate for your threat model.

Core Security Principles

Authentication & Authorization

  • Implement mutual TLS certificates for MCP connections
  • Use OAuth 2.0/2.1 for HTTP-based transports
  • Never use sessions for authentication - verify all requests
  • Bind session IDs to user-specific information
  • Rotate API keys and tokens regularly

Input Validation & Sanitization

  • Validate all inputs against MCP protocol specification
  • Implement allow-lists for tool parameters
  • Sanitize outputs to prevent prompt injection
  • Use schema validation for all messages
  • Escape special characters in returned data

Monitoring & Logging

  • Log all MCP server actions with timestamps
  • Implement anomaly detection for unusual patterns
  • Track tool usage frequency and parameters
  • Set up alerts for suspicious activities
  • Maintain audit trails for compliance

Access Control

  • Implement fine-grained permissions per tool
  • Use principle of least privilege
  • Require explicit user consent for operations
  • Implement rate limiting on all endpoints
  • Separate read and write permissions

Common Vulnerabilities & Mitigations

Indirect Prompt Injection

High

Attackers embed malicious instructions in data that the AI processes, potentially causing unauthorized actions.

Mitigation Strategies:

  • Sanitize all data returned to the AI model
  • Implement content filtering for suspicious patterns
  • Use structured output formats that separate data from instructions
  • Monitor for unusual command sequences

Example Implementation:

// Vulnerable implementation
return {
  content: userInput // Direct pass-through
};

// Secure implementation  
return {
  content: sanitizeForAI(userInput, {
    escapePromptCommands: true,
    maxLength: 1000
  })
};

Token/Credential Exposure

Critical

MCP servers store authentication tokens for multiple services, making them high-value targets.

Mitigation Strategies:

  • Encrypt tokens at rest using industry standards
  • Use secure key management systems
  • Implement token rotation policies
  • Never log sensitive credentials

Example Implementation:

// Vulnerable implementation
console.log(`Connecting with token: ${token}`);

// Secure implementation
console.log('Connecting to service...');
// Use secure storage
const encryptedToken = await keyVault.get('service_token');

Resource Exhaustion

Medium

Uncontrolled AI requests can overwhelm MCP servers or connected services.

Mitigation Strategies:

  • Implement rate limiting per user/session
  • Set timeouts for all operations
  • Limit result set sizes
  • Use pagination for large data sets

Example Implementation:

// Implement rate limiting
const rateLimiter = new RateLimiter({
  tokensPerInterval: 100,
  interval: "minute",
  fireImmediately: true
});

async function handleRequest(req) {
  if (!await rateLimiter.consume(req.userId)) {
    throw new Error("Rate limit exceeded");
  }
  // Process request
}

Security Implementation Checklist

Architecture

  • Implement defense-in-depth with multiple security layers
  • Follow Zero Trust principles - verify everything
  • Use secure transport (HTTPS/WSS) for all communications
  • Implement proper secret management
  • Design for security monitoring and incident response

Development

  • Use Static Application Security Testing (SAST)
  • Implement Software Composition Analysis (SCA)
  • Regular security code reviews
  • Keep dependencies updated
  • Follow secure coding practices

Deployment

  • Use environment-specific configurations
  • Implement proper network segmentation
  • Enable security headers for HTTP transports
  • Configure firewalls and access controls
  • Set up intrusion detection systems

Operations

  • Regular security audits and penetration testing
  • Incident response plan for MCP-specific threats
  • Security awareness training for developers
  • Vulnerability management process
  • Regular backup and recovery testing

Secure MCP Server Template

Use this template as a starting point for secure MCP server implementations:

import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { RateLimiter } from 'rate-limiter-flexible';
import { validateSchema } from './security/validation.js';
import { sanitizeOutput } from './security/sanitization.js';

class SecureMCPServer {
  constructor() {
    this.server = new Server({
      name: 'secure-mcp-server',
      version: '1.0.0',
    });
    
    // Initialize rate limiter
    this.rateLimiter = new RateLimiter({
      points: 100,
      duration: 60,
    });
    
    this.setupSecurityMiddleware();
    this.registerTools();
  }
  
  setupSecurityMiddleware() {
    // Request validation
    this.server.use(async (req, next) => {
      // Validate request schema
      if (!validateSchema(req)) {
        throw new Error('Invalid request format');
      }
      
      // Check rate limits
      try {
        await this.rateLimiter.consume(req.sessionId);
      } catch (e) {
        throw new Error('Rate limit exceeded');
      }
      
      // Log request for audit
      console.log({
        timestamp: new Date().toISOString(),
        action: req.method,
        sessionId: req.sessionId,
        params: req.params // Ensure no sensitive data logged
      });
      
      return next();
    });
  }
  
  registerTools() {
    this.server.setRequestHandler('tools/list', async () => {
      return {
        tools: [{
          name: 'secure_query',
          description: 'Execute validated queries',
          inputSchema: {
            type: 'object',
            properties: {
              query: { type: 'string', maxLength: 1000 }
            },
            required: ['query']
          }
        }]
      };
    });
    
    this.server.setRequestHandler('tools/call', async (request) => {
      const { name, arguments: args } = request.params;
      
      // Validate tool access
      if (!this.hasPermission(request.sessionId, name)) {
        throw new Error('Permission denied');
      }
      
      // Execute with timeout
      const result = await Promise.race([
        this.executeTool(name, args),
        new Promise((_, reject) => 
          setTimeout(() => reject(new Error('Timeout')), 5000)
        )
      ]);
      
      // Sanitize output
      return sanitizeOutput(result);
    });
  }
}