{"id":"GHSA-fph8-pg5w-78fv","kind":"vulnerability","aliases":["GHSA-fph8-pg5w-78fv"],"related":[],"title":"CVE-2026-87911 - Read-only enforcement bypass enabling operating system command execution in the SQL validation component of Amazon awslabs postgres-mcp-server","description":"CVE-2026-87911 - Read-only enforcement bypass enabling operating system command execution in the SQL validation component of Amazon awslabs postgres-mcp-server\n\n### CVE-2026-87911 - Read-only enforcement bypass enabling operating system command execution in the SQL validation component of Amazon awslabs postgres-mcp-server\n\nBulletin ID: 2026-104-AWS Scope: AWS Content Type: Important (requires attention) Publication Date: 09/09/2026 12:30 PM PDT\n\nDescription:\n\nawslabs.postgres-mcp-server is a python package that implements a Postgres MCP server. We found CVE-2026-87911, where an OS command injection weakness in the read-only enforcement of the SQL validation component in Amazon awslabs postgres-mcp-server before 1.1.7 might allow an unauthenticated actor to execute operating system commands on the host of a self-managed PostgreSQL server by placing a crafted COPY ... TO PROGRAM statement into content that is processed when an authenticated user interacts with the MCP server in its default read-only mode.\n\nImpacted versions:\n\nawslabs.postgres-mcp-server before 1.1.7, self-managed PostgreSQL deployment profile (PG_WIRE_PROTOCOL connection method) where the configured database role holds superuser or pg_execute_server_program.\n\nResolution:\n\nThis issue has been addressed in awslabs postgres-mcp-server (python package) version 1.1.7 in pypi.\n\nWorkarounds:\n\nThe strongest control is to connect the MCP server using a dedicated Postgres role that has only the privileges it actually needs, so that the database itself enforces the boundary regardless of what SQL reaches it. In particular:\n\n- Do not connect as a superuser, rds_superuser, or the cluster master user. Those roles bypass row-level security, can read credential catalogs (pg_authid, pg_user_mappings), and can terminate other sessions.\n- For read-only use, grant only CONNECT + USAGE + SELECT on the schemas the agent needs, and force read-only transactions at the role level.\n- For read/write use, grant only the specific INSERT/UPDATE/DELETE privileges required, scoped to the necessary schemas and tables.\n\nCombining a minimal-privilege role (database-enforced) with the blocklist (application-enforced) gives you defense in depth: even if a query slips past the blocklist, the role's privileges still bound what it can do.\n\nReferences:\n\n- CVE-2026-87911\n- GHSA-fph8-pg5w-78fv\n\nAcknowledgement:\n\nWe would like to thank Mordehai Attia (Corsen AI) and Ryan von Brubeck for collaborating on this issue through the coordinated vulnerability disclosure process.\n\n Please email aws-security@amazon.com with any security questions or concerns.","summary":"The awslabs postgres-mcp-server Python package before 1.1.7 has an OS command injection flaw in its read-only SQL validation: a crafted COPY ... TO PROGRAM statement placed in content the MCP server processes can run commands on the host of a self-managed PostgreSQL server. The advisory says an unauthenticated actor can plant the statement, but it fires when an authenticated user interacts with the server in its default read-only mode.","severity":"high","cvss":null,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["ai-agents","ai-tooling","aws","lab-disclosure","mcp","postgresql","python","self-hosted"],"not_affected_if":["least-privilege-role","managed-hosting","version-1.1.7-or-later"],"how_to_check":"- Check the installed version of the `awslabs.postgres-mcp-server` package (for example `pip show awslabs.postgres-mcp-server`); anything below `1.1.7` is exposed.\n- Check whether the server uses the self-managed PostgreSQL profile (PG_WIRE_PROTOCOL connection method) rather than a managed database.\n- Check whether the configured database role is a superuser or holds `pg_execute_server_program`, for example with `SELECT rolsuper FROM pg_roles WHERE rolname = current_user;` and `SELECT pg_has_role(current_user, 'pg_execute_server_program', 'MEMBER');`.","fix":"- Upgrade `awslabs.postgres-mcp-server` to `1.1.7` or later from PyPI.\n- Connect the MCP server with a dedicated, non-superuser role that does not hold `pg_execute_server_program`, granting only the CONNECT, USAGE and SELECT (or specific write) privileges the agent needs.\n- Do not connect as a superuser, rds_superuser or the cluster master user.","status":"open","published_at":"2026-09-09T00:00:00+00:00","first_seen_at":"2026-10-24T20:05:36+00:00","triaged_at":"2026-10-25T05:30:32+00:00","updated_at":"2026-10-25T05:30:32+00:00","category":"ai-tooling","confidence":0.8,"triage":{"at":"2026-10-25T05:30:32Z","model":"claude-haiku-5-5","output":{"fix":"- Upgrade `awslabs.postgres-mcp-server` to `1.1.7` or later from PyPI.\n- Connect the MCP server with a dedicated, non-superuser role that does not hold `pg_execute_server_program`, granting only the CONNECT, USAGE and SELECT (or specific write) privileges the agent needs.\n- Do not connect as a superuser, rds_superuser or the cluster master user.","reach":"internet","title":"awslabs postgres-mcp-server: read-only check bypass allows OS command execution","impact":"high","summary":"The awslabs postgres-mcp-server Python package before 1.1.7 has an OS command injection flaw in its read-only SQL validation: a crafted COPY ... TO PROGRAM statement placed in content the MCP server processes can run commands on the host of a self-managed PostgreSQL server. The advisory says an unauthenticated actor can plant the statement, but it fires when an authenticated user interacts with the server in its default read-only mode.","category":"ai-tooling","nicknames":[],"who_cares":["mcp","postgresql","python","self-hosted","ai-agents"],"confidence":0.8,"needs_auth":"unknown","worst_case":"Attacker runs operating system commands on the PostgreSQL database host.","analyst_note":"","how_to_check":"- Check the installed version of the `awslabs.postgres-mcp-server` package (for example `pip show awslabs.postgres-mcp-server`); anything below `1.1.7` is exposed.\n- Check whether the server uses the self-managed PostgreSQL profile (PG_WIRE_PROTOCOL connection method) rather than a managed database.\n- Check whether the configured database role is a superuser or holds `pg_execute_server_program`, for example with `SELECT rolsuper FROM pg_roles WHERE rolname = current_user;` and `SELECT pg_has_role(current_user, 'pg_execute_server_program', 'MEMBER');`.","needs_analyst":false,"not_affected_if":["version-1.1.7-or-later","managed-hosting","least-privilege-role"],"who_is_affected":"Teams running awslabs postgres-mcp-server before 1.1.7 against a self-managed PostgreSQL server where the configured role is a superuser or holds pg_execute_server_program. The exploit needs that privileged role, so a server connected through a least-privilege role is limited to what that role can do. Managed-database deployments outside the self-managed profile are not described as affected.","user_interaction":"yes","needs_special_setup":"yes","severity_if_unknown":"high"},"cost_usd":0.000873,"input_tokens":4269,"output_tokens":893,"severity_before":"unknown"},"analyst_status":null,"analyst_note":null,"search":"'-104':182C '-2026':2A,130C,155C,216C,498C '-87911':3A,131C,156C,217C,499C '09/09/2026':193C '1.1.7':61B,243C,300C,339C '12':194C '2026':181C '30':195C '78fv':30A,35A,504C 'acknowledg':505C 'actor':106B,248C 'actual':363C 'address':329C 'advisori':102B 'agent':38B,429C 'ai':37B,40B,514C 'ai-ag':36B 'ai-tool':39B 'allow':245C 'amazon':20A,148C,173C,236C 'applic':471C 'application-enforc':470C 'attent':190C 'attia':512C 'authent':116B,279C 'authid':406C 'aw':42B,183C,185C 'aws-security@amazon.com':532C 'awslab':21A,53B,149C,174C,237C,331C 'awslabs.postgres':199C,295C 'blocklist':469C,485C 'bound':491C 'boundari':372C 'brubeck':518C 'bulletin':179C 'bypass':8A,136C,161C,396C 'catalog':404C 'cluster':391C 'collabor':520C 'combin':458C 'command':12A,65B,90B,140C,165C,221C,253C 'compon':18A,146C,171C,234C 'concern':538C 'configur':314C 'connect':310C,348C,383C,422C 'content':83B,186C,273C 'control':345C 'coordin':526C 'copi':77B,268C 'corsen':513C 'craft':76B,267C 'credenti':403C 'cve':1A,129C,154C,215C,497C 'databas':315C,368C,465C 'database-enforc':464C 'date':192C 'dedic':354C 'default':124B,288C 'defens':475C 'deploy':305C 'depth':477C 'descript':198C 'disclosur':45B,528C 'email':531C 'enabl':9A,137C,162C 'enforc':7A,135C,160C,229C,370C,466C,472C 'even':478C 'execut':13A,141C,166C,250C,321C 'fire':113B 'flaw':67B 'forc':432C 'found':214C 'fph8':28A,33A,502C 'ghsa':27A,32A,501C 'ghsa-fph8-pg5w-78fv':26A,31A,500C 'give':473C 'grant':420C,444C 'hold':317C 'host':51B,93B,256C 'id':180C 'impact':293C 'implement':208C 'import':188C 'inject':66B,222C 'insert/update/delete':448C 'interact':118B,281C 'issu':326C,523C 'lab':44B 'lab-disclosur':43B 'level':399C,440C 'like':508C 'manag':98B,261C,303C 'map':409C 'master':392C 'mcp':24A,46B,56B,85B,152C,177C,201C,211C,240C,284C,297C,334C,350C 'mcp-server':200C,296C 'method':311C 'might':244C 'minim':461C 'minimal-privileg':460C 'mode':128B,292C 'mordehai':511C 'necessari':454C 'need':364C,430C 'oper':10A,138C,163C,251C 'os':64B,220C 'packag':59B,206C,337C 'particular':380C 'past':483C 'pdt':197C 'pg':307C,320C,405C,407C 'pg5w':29A,34A,503C 'place':81B,265C 'plant':108B 'pleas':530C 'pm':196C 'postgr':23A,55B,151C,176C,210C,239C,333C,355C 'postgres-mcp-serv':22A,54B,150C,175C,238C,332C 'postgresql':47B,99B,262C,304C 'privileg':361C,449C,462C,489C 'process':87B,276C,529C 'profil':306C 'program':79B,270C,323C 'protocol':309C 'public':191C 'pypi':341C 'python':48B,58B,205C,336C 'queri':481C 'question':536C 'rds':387C 'reach':377C 'read':5A,71B,126B,133C,158C,227C,290C,402C,417C,434C 'read-on':4A,70B,125B,132C,157C,226C,289C,416C,433C 'read/write':442C 'refer':496C 'regardless':373C 'requir':189C,450C 'resolut':324C 'role':316C,356C,395C,439C,463C,487C 'row':398C 'row-level':397C 'run':89B 'ryan':516C 'say':103B 'schema':427C,455C 'scope':184C,451C 'secur':400C,535C 'select':424C 'self':50B,97B,260C,302C 'self-host':49B 'self-manag':96B,259C,301C 'server':25A,57B,86B,100B,121B,153C,178C,202C,212C,241C,263C,285C,298C,322C,335C,351C 'session':414C 'slip':482C 'specif':447C 'sql':16A,73B,144C,169C,232C,376C 'statement':80B,110B,271C 'still':490C 'strongest':344C 'superus':318C,386C,388C 'system':11A,139C,164C,252C 'tabl':457C 'termin':412C 'thank':510C 'tool':41B 'transact':436C 'type':187C 'unauthent':105B,247C 'usag':423C 'use':352C,419C,443C 'user':117B,280C,393C,408C 'valid':17A,74B,145C,170C,233C 'version':294C,338C 'von':517C 'vulner':527C 'weak':223C 'wire':308C 'workaround':342C 'would':507C","nicknames":[],"mitigations":[],"who_affected":"Teams running awslabs postgres-mcp-server before 1.1.7 against a self-managed PostgreSQL server where the configured role is a superuser or holds pg_execute_server_program. The exploit needs that privileged role, so a server connected through a least-privilege role is limited to what that role can do. Managed-database deployments outside the self-managed profile are not described as affected.","tier":"B","verified":{},"analyst_revisit_at":null,"first_public_at":"2026-09-09T00:00:00+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"lab","external_id":"https://aws.amazon.com/security/security-bulletins/rss/2026-104-aws/#GHSA-fph8-pg5w-78fv","url":"https://aws.amazon.com/security/security-bulletins/rss/2026-104-aws/","severity":null,"published_at":"2026-09-09T00:00:00+00:00","modified_at":null,"first_seen_at":"2026-10-24T20:05:36+00:00","fetched_at":"2026-10-24T20:05:36+00:00","note":"AWS: CVE-2026-87911 - Read-only enforcement bypass enabling operating system command execution in the SQL validation component of Amazon awslabs postgres-mcp-server"}],"documents":[{"id":2973,"url":"https://aws.amazon.com/security/security-bulletins/rss/2026-104-aws/","title":"AWS: CVE-2026-87911 - Read-only enforcement bypass enabling operating system command execution in the SQL validation component of Amazon awslabs postgres-mcp-server","kind":"advisory","source":"lab","text":"CVE-2026-87911 - Read-only enforcement bypass enabling operating system command execution in the SQL validation component of Amazon awslabs postgres-mcp-server\n\n### CVE-2026-87911 - Read-only enforcement bypass enabling operating system command execution in the SQL validation component of Amazon awslabs postgres-mcp-server\n\nBulletin ID: 2026-104-AWS Scope: AWS Content Type: Important (requires attention) Publication Date: 09/09/2026 12:30 PM PDT\n\nDescription:\n\nawslabs.postgres-mcp-server is a python package that implements a Postgres MCP server. We found CVE-2026-87911, where an OS command injection weakness in the read-only enforcement of the SQL validation component in Amazon awslabs postgres-mcp-server before 1.1.7 might allow an unauthenticated actor to execute operating system commands on the host of a self-managed PostgreSQL server by placing a crafted COPY ... TO PROGRAM statement into content that is processed when an authenticated user interacts with the MCP server in its default read-only mode.\n\nImpacted versions:\n\nawslabs.postgres-mcp-server before 1.1.7, self-managed PostgreSQL deployment profile (PG_WIRE_PROTOCOL connection method) where the configured database role holds superuser or pg_execute_server_program.\n\nResolution:\n\nThis issue has been addressed in awslabs postgres-mcp-server (python package) version 1.1.7 in pypi.\n\nWorkarounds:\n\nThe strongest control is to connect the MCP server using a dedicated Postgres role that has only the privileges it actually needs, so that the database itself enforces the boundary regardless of what SQL reaches it. In particular:\n\n- Do not connect as a superuser, rds_superuser, or the cluster master user. Those roles bypass row-level security, can read credential catalogs (pg_authid, pg_user_mappings), and can terminate other sessions.\n- For read-only use, grant only CONNECT + USAGE + SELECT on the schemas the agent needs, and force read-only transactions at the role level.\n- For read/write use, grant only the specific INSERT/UPDATE/DELETE privileges required, scoped to the necessary schemas and tables.\n\nCombining a minimal-privilege role (database-enforced) with the blocklist (application-enforced) gives you defense in depth: even if a query slips past the blocklist, the role's privileges still bound what it can do.\n\nReferences:\n\n- CVE-2026-87911\n- GHSA-fph8-pg5w-78fv\n\nAcknowledgement:\n\nWe would like to thank Mordehai Attia (Corsen AI) and Ryan von Brubeck for collaborating on this issue through the coordinated vulnerability disclosure process.\n\n Please email aws-security@amazon.com with any security questions or concerns.","published_at":"2026-09-09T00:00:00+00:00","relation":"advisory","confidence":null,"note":null}],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}