pgEdge Postgres MCP Server before 1.1.0: read_only bypass, pl-do SQL injection and five more flaws (CVE-2026-126196, CVE-2026-126197 and others)
pgEdge Postgres MCP Server 1.0.0 and earlier (including all alpha and beta pre-releases) has seven disclosed flaws fixed in 1.1.0. The two high ones let an MCP caller write to a database through a connection configured as read_only, and run arbitrary SQL through custom pl-do tools. Upgrade to 1.1.0 and review database audit logs, since upgrading does not tell you whether anything was already run.
What it is
CVE-2026-126196 / GHSA-j7mp-839j-jrm7 (high): query_database sent statements it did not recognise as reads through pgx Exec without bind parameters, i.e. PostgreSQL's simple query protocol, which accepts several semicolon-separated statements. With transaction syntax such as SET SESSION CHARACTERISTICS, RESET ALL or DISCARD ALL a caller could create, alter and drop objects on a read_only connection, and pooled session state could leave later calls writable. Affects deployments that rely on read_only and connect with a role that has write privileges.
CVE-2026-126197 / GHSA-r5pp-jx86-r6r9 (high, CVSS 8.8): custom pl-do tools interpolated JSON arguments into a DO block delimited by the fixed dollar-quote tag $mcp_custom_tool$ (and $mcp_args$ for plpgsql). An argument containing the tag closed the block, so the caller could run any SQL as the connecting role, bypassing read_only. Only deployments with at least one pl-do custom tool are affected; sql and pl-func tools use bind parameters.
CVE-2026-126198 and CVE-2026-126199: the bundled CLI and web clients decided whether to ask for write confirmation by tool name and by the first SQL keyword only, so custom tools, SELECT INTO, data-modifying WITH queries and EXPLAIN ANALYZE of a write ran without confirmation on allow_writes connections, including when a model followed instructions in retrieved content.
CVE-2026-125320: the optional HTTP transport did not validate the Origin header, so a web page could use DNS rebinding to reach a locally running server and read schemas and query results. CVE-2026-125321: login rate limiting trusted the leftmost X-Forwarded-For value. CVE-2026-125322: the where parameter of count_rows accepted subqueries against other tables, a row-count oracle for any table the role can read.
How to check
- Check the server version (pgedge-postgres-mcp-server) and whether it is 1.0.0 or earlier.
- Check whether you rely on read_only connections with a role that holds write privileges, define pl-do custom tools, or run the HTTP transport on a machine with a browser.
How to fix
- Upgrade pgEdge Postgres MCP Server (and the bundled CLI/web client) to 1.1.0 or later.
- Review PostgreSQL audit logs for unexpected DDL/DML or statements run alongside DO blocks through the MCP connection.
- Until you can upgrade: connect with a role that has no write privileges, and remove or disable pl-do custom tools. pgEdge notes a read-only role stops writes but not reads of anything the role can read.
-- give the MCP connection a role that cannot write
CREATE ROLE mcp_reader LOGIN PASSWORD '...';
GRANT CONNECT ON DATABASE mydb TO mcp_reader;
GRANT USAGE ON SCHEMA public TO mcp_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO mcp_reader; Sources
- GitHub advisory GHSA-j7mp-839j-jrm7 (read_only bypass) ↗
- GitHub advisory GHSA-r5pp-jx86-r6r9 (pl-do SQL injection) ↗
- NVD: CVE-2026-126196 ↗
- NVD: CVE-2026-126197 ↗
- NVD: CVE-2026-126198 ↗
- NVD: CVE-2026-126199 ↗
- NVD: CVE-2026-125320 ↗
- NVD: CVE-2026-125321 ↗
- NVD: CVE-2026-125322 ↗
- pgEdge Postgres MCP v1.1.0 release ↗
- criticalMalicious npm and PyPI packages posing as AI and MCP tools: depfix-ai, agent-trace-kit, @go-gost/mcp-darwin-x64 and my-mcp-server-driving-license-ocr
- criticalMalicious npm packages posing as MCP servers: @rfewqa-fes/mnm-doc-mcp, @lemili9804/mcp-weather-server and mcp-contract-tester
- criticalMalicious code in @bestcoolman/dev-mcp (npm)
- criticalMalicious code in @massnerder/x402-scraper-mcp (npm)