Agents & MCPImpact: High
Postgres Model Context Protocol Server Vulnerability Allows Remote Code Execution
AWS published CVE-2026-87911 (CVSS 9.6) in its postgres-mcp-server where read-only mode can be bypassed using PostgreSQL COPY TO PROGRAM syntax. An untrusted prompt processed by an agent can execute shell commands on the host if the database role has elevated privileges.

Why it matters
Strip elevated Postgres roles from agent database connections today to prevent prompt-injection attacks from breaking out into host shell access.
TL;DR
- 01Application-layer regex denylists cannot reliably enforce database read-only constraints.
- 02Postgres COPY ... TO PROGRAM executes external shell commands even inside BEGIN READ ONLY transactions.
- 03AWS RDS and Aurora protect against this privilege escalation by default, but self-hosted Postgres instances are fully vulnerable.
Key facts
- CVE Identifier
- CVE-2026-87911
- CVSS Score
- 9.6 Critical
- Patched Version
- postgres-mcp-server 1.1.7
- Attack Vector
- PR:N/UI:R (Unauthenticated prompt plant)
The Regex Denylist Trap. AWS Labs postgres-mcp-server attempted to guard read-only operations via Python regex matching in mutable_sql_detector.py, blocking mutating keywords like INSERT, UPDATE, and DROP. However, Postgres includes COPY ... TO PROGRAM, which pipes query results into host shell commands. Because this operation modifies host state rather than table data, standard BEGIN READ ONLY transaction wrappers do not catch or stop it. ### Command Injection via Planted Prompts. Assigned CVE-2026-87911 with a CVSS 9.6 rating, the vulnerability allows an unauthenticated attacker to place malicious strings into external content processed by an agent. When the agent submits the generated query, the host executes arbitrary OS instructions if connecting as superuser or a member of pg_execute_server_program. RDS and Aurora environments prevent assigning this role, confining direct host exploitation to self-managed Postgres deployments. ### The Proper Four-Step Role Audit. Defense-in-depth requires enforcing least privilege in the database rather than expanding regex lists. First, query pg_has_role to check if your MCP connection role holds pg_execute_server_program. Second, update postgres-mcp-server to version 1.1.7 or later to ensure COPY_PROGRAM_PATTERN is present. Finally, explicitly strip all host-level execution roles and grant only CONNECT, USAGE, and SELECT on targeted application schemas.
Try it in 2 minutes
SELECT pg_has_role(rolname, 'pg_execute_server_program', 'member') AS exec_program FROM pg_roles WHERE rolname = current_user;sql
✓ When to use
- Connecting Claude or Cursor agents to PostgreSQL databases for analytics and schema exploration.
- Auditing tool safety when deploying agentic workflows against internal infrastructure.
✕ When NOT to use
- Do not rely on software-layer read-only flags when the database user has superuser privileges.
- Do not expose unpinned legacy MCP database servers to untrusted user input.
What to do today
- Update postgres-mcp-server to version 1.1.7 or higher on PyPI.
- Check database user roles to revoke pg_execute_server_program and superuser privileges.
- Restrict MCP database user permissions strictly to CONNECT, USAGE, and SELECT.