Skip to content

Security: neverinfamous/mysql-mcp

SECURITY.md

πŸ”’ Security Policy

The mysql-mcp server protects your databases. It secures stdio, HTTP, and SSE transports.

πŸ’Ž Value Proposition

MySQL MCP is a production-ready integration engineered for AI agents. It minimizes LLM token consumption by up to 90% via sandboxed Code Mode. It scales reliably through built-in connection pooling. It secures database access using strict OAuth 2.1 validation.

πŸ›‘οΈ Secure Your Database

Prevent SQL Injection

Identifier Sanitization (src/utils/identifiers.ts)

  • βœ… Comprehensive coverage β€” validates and quotes all table, column, schema, and index names across all 28 tool groups.
  • βœ… MySQL identifier rules enforced β€” start with letter/underscore, contain only alphanumerics, underscores, or $ signs
  • βœ… 64-character limit enforced (MySQL maximum)
  • βœ… Invalid identifiers throw InvalidIdentifierError

Key functions:

  • sanitizeIdentifier(name) β€” Validates and double-quotes an identifier
  • sanitizeTableName(table, schema?) β€” Handles schema-qualified table references
  • sanitizeColumnRef(column, table?) β€” Handles column references with optional table qualifier
  • sanitizeIdentifiers(names[]) β€” Batch sanitization for column lists

Parameterized Queries

  • βœ… All user-provided values use parameterized queries via mysql2 library
  • βœ… Identifier sanitization complements parameterized values β€” defense in depth

Handle Errors Structurally

Every tool returns structured error responses β€” never raw exceptions or internal details:

{
  "success": false,
  "error": "Descriptive message with context",
  "code": "MODULE_ERROR_CODE",
  "category": "VALIDATION_ERROR",
  "suggestion": "Actionable remediation hint",
  "recoverable": true
}

Error logic leverages the MySQLMcpError hierarchy (9 distinct categories). It returns enriched payloads via formatHandlerError(). Error codes are module-prefixed. Internal stack traces are logged server-side but never exposed to clients.

πŸ” Validate Your Inputs

  • βœ… Zod schemas β€” all tool inputs validated at tool boundaries before database operations
  • βœ… Parameterized queries used throughout β€” never string interpolation
  • βœ… Audit filters required β€” audit log queries must provide at least one filter to prevent mass data extraction
  • βœ… Data masking aliases β€” validated strictly at the MCP boundary to prevent evasion
  • βœ… Identifier sanitization β€” table, column, schema, and index names validated against injection

πŸ“ Enforce Filesystem Boundaries

A dedicated security sandbox strictly confines all file I/O operations exposed by the server. This includes MySQL Shell operations and Audit Subsystem snapshots.

  • βœ… ALLOWED_IO_ROOTS Enforcement β€” operations must target absolute paths within administrator-configured directories. HTTP transports hard-fail on startup if omitted.
  • βœ… Path Traversal Prevention β€” blocks directory traversal sequences (..), null bytes, and query parameters in path inputs.
  • βœ… Symlink Awareness β€” resolves and asserts realpath to prevent escaping the sandbox via symlink targets.
  • βœ… Hidden Files Protection β€” rejects dotfiles and hidden directories (unless explicitly authorized by the root config).
  • βœ… Drive Letter Validation β€” fully cross-platform compatible with strict Windows drive letter (C:\) and UNC path checking.

πŸ§ͺ Secure Code Mode Sandbox

Code Mode executes user-provided JavaScript in a hardened isolated-vm sandbox. This includes multiple layers of defense-in-depth and fleet-standard restrictions. These features are detailed prominently in the README.md.

Enforce Engine-Level Restrictions

  • βœ… Strict V8 Isolate Boundary β€” executes within a physically separate V8 isolate. It ensures native objects and prototypes cannot cross the boundary.
  • βœ… Memory & CPU Constraints β€” enforced at the C++ level. This includes synchronous timeouts and strict heap limits.
  • βœ… API Bindings via Reference β€” all MySQL API methods are securely injected into the isolate using ivm.Reference wrappers.

Validate Code Statically

  • βœ… 29 blocked patterns β€” regex rules block require(), import(), eval(), process, and __proto__. They also block filesystem/network access and system commands.
  • βœ… Unicode & Comment Sanitization β€” performs NFKC normalization and strips all comments before pattern validation to prevent regex evasion.
  • βœ… 50KB code input limit β€” prevents payload-based resource exhaustion.

Protect the Runtime

  • βœ… RPC Quotas β€” strict cap of 100 API calls per execution to prevent unbounded loops.
  • βœ… Execution timeout β€” 30s hard limit (not configurable, enforced by the isolate engine) to prevent resource exhaustion.
  • βœ… Egress boundary enforcement β€” streaming JSON.stringify serialization aborts mid-flight when exceeding size caps (default 100KB).
  • βœ… Rate limiting β€” 60 executions per minute per client. Distributed across deployments via Redis if REDIS_URL is provided, with graceful in-memory fallback.
  • βœ… Readonly enforcement β€” when readonly: true, write methods return structured errors instead of executing.
  • βœ… Audit logging β€” every execution logged with UUID, client ID, metrics, and redacted code preview.
  • βœ… Admin scope β€” Code Mode requires admin scope when OAuth is enabled.

🌐 Secure HTTP Transports

When running in HTTP mode (--transport http), the following security measures apply:

Add Security Headers

  • βœ… DNS Rebinding Protection β€” validateHostHeader() strictly validates Host headers
  • βœ… X-Content-Type-Options: nosniff β€” prevents MIME sniffing
  • βœ… X-Frame-Options: DENY β€” prevents clickjacking
  • βœ… Content-Security-Policy: default-src 'none'; frame-ancestors 'none' β€” prevents XSS and framing
  • βœ… Cache-Control: no-store, no-cache, must-revalidate β€” prevents caching of sensitive data
  • βœ… Referrer-Policy: no-referrer β€” prevents referrer leakage
  • βœ… Permissions-Policy: camera=(), microphone=(), geolocation=() β€” restricts browser APIs

Support HSTS

  • βœ… Strict-Transport-Security header for HTTPS deployments
  • βœ… Enable via --enable-hsts flag or MCP_ENABLE_HSTS=true

Configure CORS

  • βœ… Origin whitelist with Vary: Origin header for caching
  • βœ… Optional credentials support (corsAllowCredentials)
  • βœ… MCP-specific headers allowed (X-Session-ID, mcp-session-id)

Apply Rate Limiting

  • βœ… Built-in Rate Limiting β€” 100 requests/minute per IP. Distributed across deployments via Redis if REDIS_URL is provided, with graceful in-memory fallback.
  • βœ… Health Endpoint Bypass β€” /health bypasses limits to ensure reliable load balancer checks
  • βœ… Returns 429 Too Many Requests with proper Retry-After headers when limits are exceeded
  • βœ… Slowloris DoS Protection β€” configurable read timeouts via MCP_REQUEST_TIMEOUT and MCP_HEADERS_TIMEOUT

Reverse Proxy Note: The server uses req.socket.remoteAddress for rate limiting. Behind a reverse proxy (e.g., nginx, Cloudflare Tunnel), all requests may share the same source IP. You must ensure your proxy forwards distinct client IPs. Alternatively, you can apply rate limiting at the proxy layer instead.

Restrict Request Limits

  • βœ… Memory Exhaustion Protection β€” Strict request bounds prevent memory exhaustion DoS

πŸ”‘ Authenticate with OAuth 2.1

Full OAuth 2.1 for production multi-tenant deployments is supported. These enterprise security features are detailed prominently in the README.md.

  • βœ… RFC 9728 Protected Resource Metadata (/.well-known/oauth-protected-resource)
  • βœ… RFC 8414 Authorization Server Discovery with caching
  • βœ… RFC 7591 OAuth 2.1 Dynamic Client Registration
  • βœ… JWT validation with JWKS support (TTL: 1 hour, configurable)
  • βœ… MySQL-specific scopes: read, write, admin, full, db:{name}, schema:{name}, table:{schema}:{table}
  • βœ… Per-tool scope enforcement via AsyncLocalStorage context threading

⚠️ HTTP without OAuth: When OAuth is not configured, all scope checks are bypassed. If you expose the HTTP transport without enabling OAuth, any client has full unrestricted access. Always enable OAuth for production HTTP deployments.

🐳 Harden Docker Containers

Run as Non-Root User

  • βœ… Dedicated user: app (UID 1001) with minimal privileges
  • βœ… Restricted group: app (GID 1001)
  • βœ… Restricted data directory: 700 permissions

Harden the Container

  • βœ… Minimal base image: node:24-alpine
  • βœ… Multi-stage build: Build dependencies not in production image
  • βœ… Production pruning: npm prune --omit=dev after build
  • βœ… Health check: Built-in HEALTHCHECK instruction (transport-aware for HTTP/SSE/stdio)
  • βœ… Process isolation from host system

Patch Dependencies

The Dockerfile patches npm-bundled transitive dependencies for Docker Scout compliance:

  • βœ… cross-spawn β€” CVE-2024-21538
  • βœ… glob β€” CVE-2025-64756
  • βœ… @isaacs/brace-expansion@5.0.1 β€” CVE-2025-5889
  • βœ… tar@7.5.19 β€” CVE-2026-26960
  • βœ… minimatch@10.2.5 β€” CVE-2026-27904, CVE-2026-27903

Mount Volumes Securely

# Secure volume mounting
docker run -v ./data:/app/data:rw,noexec,nosuid,nodev writenotenow/mysql-mcp:latest

Apply Resource Limits

# Apply resource limits
docker run --memory=1g --cpus=1 writenotenow/mysql-mcp:latest

πŸ” Secure Your Logs

Enable Audit Subsystem

  • βœ… Full JSONL Audit Trails β€” comprehensive logging array capturing mutations, Code Mode executions, and system events
  • βœ… Session Token Estimates β€” robust burn-rate tracking appended to log entries
  • βœ… Pre-Mutation Snapshots β€” interceptor captures table states before destructive administration operations

Redact Credentials

  • βœ… Sensitive fields automatically redacted in logs: password, secret, token, apikey, issuer, audience, jwksUri, credentials, etc.
  • βœ… Recursive sanitization for nested objects

Prevent Log Injection

  • βœ… Control character sanitization (ASCII 0x00-0x1F except tab/newline, 0x7F, C1 characters)
  • βœ… Prevents log forging and escape sequence attacks

πŸ”„ Secure CI/CD Pipelines

  • βœ… CodeQL analysis β€” automated static analysis on push/PR
  • βœ… pnpm audit β€” dependency vulnerability checking (audit-level: moderate)
  • βœ… Dependabot β€” automated dependency update PRs (weekly for npm and GitHub Actions)
  • βœ… Secrets scanning β€” dedicated workflow for leaked credential detection
  • βœ… E2E transport parity β€” Playwright suite validates HTTP/SSE security behavior

🚨 Follow Security Best Practices

Follow Best Practices for Users

  1. Never commit database credentials to version control β€” use environment variables
  2. Use OAuth 2.1 authentication for HTTP transport in production β€” never expose HTTP transport without OAuth
  3. Restrict database user permissions to minimum required
  4. Enable SSL for database connections in production (ssl=true in connection string)
  5. Enable HSTS when running over HTTPS (--enable-hsts)
  6. Configure CORS origins explicitly β€” avoid wildcards
  7. Use resource limits β€” apply Docker --memory and --cpus limits
  8. Apply rate limiting at the proxy layer when deploying behind a reverse proxy
  9. Consider SHA-pinning critical GitHub Actions in CI workflows for supply-chain defense-in-depth

Follow Best Practices for Developers

  1. Parameterized queries only β€” never interpolate user input into SQL strings
  2. Zod validation β€” all tool inputs validated via schemas at tool boundaries
  3. No secrets in code β€” use environment variables (.env files are gitignored)
  4. Typed error classes β€” descriptive messages with context; don't expose internals
  5. Regular updates β€” keep Node.js and npm dependencies updated
  6. Security scanning β€” regularly scan Docker images for vulnerabilities

πŸ“‹ Complete the Security Checklist

  • Parameterized SQL queries throughout
  • Identifier sanitization (table, column, schema, index names)
  • Input validation via Zod schemas
  • Filesystem boundary sandbox (ALLOWED_IO_ROOTS) for all file I/O operations
  • Code Mode sandbox isolation (true separate V8 isolate via isolated-vm)
  • Code Mode V8 codeGeneration restrictions (eval/Function disabled at engine level)
  • Code Mode native prototype isolation (objects cannot cross isolate boundary)
  • Code Mode blocked patterns (29 static regex rules + Unicode/NFKC validation)
  • Code Mode RPC quotas (100 calls per execution)
  • Code Mode streaming egress boundary (abort serialization on oversized results)
  • Code Mode execution timeout (30s hard limit)
  • Code Mode rate limiting (60 executions/min, Redis-backed with in-memory fallback)
  • Code Mode audit logging
  • HTTP bounds limits
  • Configurable CORS with origin whitelist
  • Rate limiting (100 req/min per IP, Redis-backed with in-memory fallback)
  • Slowloris DoS timeouts (MCP_REQUEST_TIMEOUT, MCP_HEADERS_TIMEOUT)
  • DNS rebinding protection via Host header validation
  • Security headers (CSP, X-Content-Type-Options, X-Frame-Options, Cache-Control, Referrer-Policy, Permissions-Policy)
  • HSTS (opt-in)
  • OAuth 2.1 with JWT/JWKS validation (RFC 9728, RFC 8414)
  • MySQL-specific scope enforcement (read, write, admin, full, db:*, schema:*, table:*:*)
  • Per-tool scope enforcement via AsyncLocalStorage
  • Credential redaction in logs
  • Log injection prevention
  • Non-root Docker user
  • Multi-stage Docker build with production pruning
  • Transitive dependency CVE patching in Dockerfile
  • CI/CD security pipeline (CodeQL, pnpm audit, secrets scanning)
  • Structured error responses (no internal details leaked)
  • Comprehensive security documentation

🚨 Report Security Issues

Version Supported
3.x.x βœ…
2.x.x βœ…
1.x.x βœ…
< 1.0 ❌

If you discover a security vulnerability:

  1. Do not open a public GitHub issue
  2. Email security concerns to: admin@adamic.tech
  3. Include detailed reproduction steps and potential impact
  4. Allow reasonable time for a fix before public disclosure

Response Timeline

  • Initial Response: Within 48 hours
  • Status Update: Within 7 days
  • Fix Timeline: Depends on severity

We appreciate responsible disclosure and will acknowledge your contribution in our release notes (unless you prefer to remain anonymous).

πŸ”„ Apply Security Updates

  • Container updates: Rebuild Docker images when base images are updated
  • Dependency updates: Keep npm packages updated via pnpm audit and Dependabot
  • Database maintenance: Run OPTIMIZE TABLE and ANALYZE TABLE regularly for optimal performance
  • Security patches: Apply host system security updates

The mysql-mcp server is designed with security-first principles. It protects your databases. It maintains excellent performance and full MySQL capability.

There aren't any published security advisories