CVE-2026-17351 (GCVE-0-2026-17351)
Vulnerability from cvelistv5 – Published: 2026-07-31 16:00 – Updated: 2026-08-01 03:56
VLAI
EPSS
VEX
Title
pgAdmin 4: AI Assistant read-only transaction bypass via sqlparse/PostgreSQL lexer disagreement (incomplete fix for CVE-2026-12045)
Summary
The fix for CVE-2026-12045 in pgAdmin 4 9.16 required the LLM-supplied query passed to the AI Assistant's execute_sql_query tool to parse, via sqlparse, as exactly one non-transaction-control statement before running it inside a BEGIN TRANSACTION READ ONLY wrapper. sqlparse's string-literal lexing can disagree with PostgreSQL's own parser: under standard_conforming_strings = on (PostgreSQL's default since 9.1), a backslash immediately before a quote is an ordinary character to PostgreSQL, but sqlparse treats it as escaping the quote. A payload such as SELECT '\';COMMIT;CREATE TABLE pwn(x int);SELECT 1 --' therefore parses as a single SELECT to sqlparse's validator, while PostgreSQL executes it as four statements: the smuggled COMMIT ends the wrapping read-only transaction, and the trailing ROLLBACK becomes a no-op. This reintroduces the same write/RCE bypass CVE-2026-12045 was meant to close, reachable via the same indirect prompt-injection delivery (an attacker plants the payload in any object the AI Assistant may read; the LLM emits it as a tool call).
An initial candidate fix ran the query with psycopg's execute(..., prepare=True), intending to force PostgreSQL's own Parse step (extended query protocol) to reject multi-statement text regardless of sqlparse's classification. This candidate fix does not work as submitted: psycopg3's PrepareManager silently ignores the prepare argument whenever the connection's prepare_threshold is None, which is pgAdmin's default for every server connection (the per-server "Prepare threshold" field is blank unless an administrator explicitly sets it) -- psycopg3 falls back to the simple query protocol, the same multi-statement-capable path the bypass exploits, so the candidate fix closes nothing on any real-world default configuration.
The corrected fix sets conn.prepare_threshold = 0 directly on the dedicated, single-use read-only connection the AI Assistant tool opens, structurally forcing the extended query protocol independent of any server-level configuration. Verified against a live PostgreSQL 18 instance: the payload executes successfully under the prepare_threshold=None (default) behavior, and is rejected with "cannot insert multiple commands into a prepared statement" once prepare_threshold=0 is set on that connection.
This issue affects pgAdmin 4: from 9.13 before 9.17.
Severity
9 (Critical)
SSVC
Exploitation: none
Automatable: no
Technical Impact: total
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-07-31 00:00 UTC
CWE
Assigner
References
3 references
| URL | Tags |
|---|---|
| https://github.com/pgadmin-org/pgadmin4/issues/10192 | issue-tracking |
| https://github.com/pgadmin-org/pgadmin4/commit/ef… | patch |
| https://github.com/pgadmin-org/pgadmin4/commit/bf… | related |
Impacted products
1 product
| Vendor | Product | Version | CPE status | |
|---|---|---|---|---|
| pgadmin.org | pgAdmin 4 |
Affected:
9.13 , < 9.17
(custom)
|
guessed |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-17351",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "total"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-07-31T00:00:00+00:00",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-08-01T03:56:14.973Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"defaultStatus": "unaffected",
"modules": [
"AI Assistant",
"LLM Tools"
],
"product": "pgAdmin 4",
"programFiles": [
"https://github.com/pgadmin-org/pgadmin4/blob/master/web/pgadmin/llm/tools/database.py"
],
"repo": "https://github.com/pgadmin-org/pgadmin4",
"vendor": "pgadmin.org",
"versions": [
{
"lessThan": "9.17",
"status": "affected",
"version": "9.13",
"versionType": "custom"
}
]
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Kai Aizen (SnailSploit)"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Kundan Sable \u003ckundan.sable@enterprisedb.com\u003e"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Ashesh Vashi \u003cashesh.vashi@enterprisedb.com\u003e"
},
{
"lang": "en",
"type": "remediation reviewer",
"value": "Ashesh Vashi \u003cashesh.vashi@enterprisedb.com\u003e"
}
],
"descriptions": [
{
"lang": "en",
"value": "The fix for CVE-2026-12045 in pgAdmin 4 9.16 required the LLM-supplied query passed to the AI Assistant\u0027s execute_sql_query tool to parse, via sqlparse, as exactly one non-transaction-control statement before running it inside a BEGIN TRANSACTION READ ONLY wrapper. sqlparse\u0027s string-literal lexing can disagree with PostgreSQL\u0027s own parser: under standard_conforming_strings = on (PostgreSQL\u0027s default since 9.1), a backslash immediately before a quote is an ordinary character to PostgreSQL, but sqlparse treats it as escaping the quote. A payload such as SELECT \u0027\\\u0027;COMMIT;CREATE TABLE pwn(x int);SELECT 1 --\u0027 therefore parses as a single SELECT to sqlparse\u0027s validator, while PostgreSQL executes it as four statements: the smuggled COMMIT ends the wrapping read-only transaction, and the trailing ROLLBACK becomes a no-op. This reintroduces the same write/RCE bypass CVE-2026-12045 was meant to close, reachable via the same indirect prompt-injection delivery (an attacker plants the payload in any object the AI Assistant may read; the LLM emits it as a tool call).\n\nAn initial candidate fix ran the query with psycopg\u0027s execute(..., prepare=True), intending to force PostgreSQL\u0027s own Parse step (extended query protocol) to reject multi-statement text regardless of sqlparse\u0027s classification. This candidate fix does not work as submitted: psycopg3\u0027s PrepareManager silently ignores the prepare argument whenever the connection\u0027s prepare_threshold is None, which is pgAdmin\u0027s default for every server connection (the per-server \"Prepare threshold\" field is blank unless an administrator explicitly sets it) -- psycopg3 falls back to the simple query protocol, the same multi-statement-capable path the bypass exploits, so the candidate fix closes nothing on any real-world default configuration.\n\nThe corrected fix sets conn.prepare_threshold = 0 directly on the dedicated, single-use read-only connection the AI Assistant tool opens, structurally forcing the extended query protocol independent of any server-level configuration. Verified against a live PostgreSQL 18 instance: the payload executes successfully under the prepare_threshold=None (default) behavior, and is rejected with \"cannot insert multiple commands into a prepared statement\" once prepare_threshold=0 is set on that connection.\n\nThis issue affects pgAdmin 4: from 9.13 before 9.17."
}
],
"metrics": [
{
"cvssV3_1": {
"attackComplexity": "LOW",
"attackVector": "NETWORK",
"availabilityImpact": "HIGH",
"baseScore": 9,
"baseSeverity": "CRITICAL",
"confidentialityImpact": "HIGH",
"integrityImpact": "HIGH",
"privilegesRequired": "LOW",
"scope": "CHANGED",
"userInteraction": "REQUIRED",
"vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H",
"version": "3.1"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "Threat model: identical to CVE-2026-12045 -- indirect prompt injection. An attacker with low-privilege DB write access plants a payload in any object the AI Assistant might read (table row, column value, comment). When a pgAdmin user with a higher-privilege database role (typically superuser or holder of pg_execute_server_program) opens the AI Assistant against that content, the LLM emits the lexer-differential payload as a tool call, which smuggles a COMMIT past the intended read-only guard and can chain to COPY ... TO PROGRAM for OS code execution. Scored identically to the original CVE-2026-12045 record for consistency, since this is the same vulnerability surviving an incomplete fix rather than a functionally different bug: S:C for the confused-deputy pattern (attacker is not the LLM user; third-party DB content steers the user\u0027s own LLM session into unauthorised writes)."
}
]
},
{
"cvssV4_0": {
"baseScore": 9.4,
"baseSeverity": "CRITICAL",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H",
"version": "4.0"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "Same reasoning as the CVSS 3.1 entry and as the original CVE-2026-12045 record: indirect prompt injection, third-party content drives the user\u0027s LLM session, COPY ... TO PROGRAM reaches the DB host. VC:H/VI:H/VA:H + SC:H/SI:H/SA:H since RCE on the DB host compromises both pgAdmin\u0027s authority and the downstream system. UI:P captures that the user merely uses the AI Assistant normally."
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-89",
"description": "CWE-89 Improper Neutralization of Special Elements used in an SQL Command (\u0027SQL Injection\u0027)",
"lang": "en",
"type": "CWE"
},
{
"cweId": "CWE-115",
"description": "CWE-115 Misinterpretation of Input",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-07-31T16:00:19.103Z",
"orgId": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
"shortName": "PostgreSQL"
},
"references": [
{
"tags": [
"issue-tracking"
],
"url": "https://github.com/pgadmin-org/pgadmin4/issues/10192"
},
{
"tags": [
"patch"
],
"url": "https://github.com/pgadmin-org/pgadmin4/commit/ef76102bcd1cdb544eb9b4ef18d3382f22b76752"
},
{
"tags": [
"related"
],
"url": "https://github.com/pgadmin-org/pgadmin4/commit/bf4792444446f0e7ab721d23cbd6bfe6afaa7a8b"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "pgAdmin 4: AI Assistant read-only transaction bypass via sqlparse/PostgreSQL lexer disagreement (incomplete fix for CVE-2026-12045)"
}
},
"cveMetadata": {
"assignerOrgId": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
"assignerShortName": "PostgreSQL",
"cveId": "CVE-2026-17351",
"datePublished": "2026-07-31T16:00:19.103Z",
"dateReserved": "2026-07-25T02:52:57.350Z",
"dateUpdated": "2026-08-01T03:56:14.973Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2",
"vulnerability-lookup:meta": {
"epss": {
"cve": "CVE-2026-17351",
"date": "2026-10-31",
"epss": "0.00483",
"percentile": "0.41659"
},
"nvd": {
"cve": {
"affected": [
{
"affectedData": [
{
"defaultStatus": "unaffected",
"modules": [
"AI Assistant",
"LLM Tools"
],
"product": "pgAdmin 4",
"programFiles": [
"https://github.com/pgadmin-org/pgadmin4/blob/master/web/pgadmin/llm/tools/database.py"
],
"repo": "https://github.com/pgadmin-org/pgadmin4",
"vendor": "pgadmin.org",
"versions": [
{
"lessThan": "9.17",
"status": "affected",
"version": "9.13",
"versionType": "custom"
}
]
}
],
"source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007"
}
],
"configurations": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:pgadmin:pgadmin_4:*:*:*:*:*:postgresql:*:*",
"matchCriteriaId": "DA305ECD-4B65-4A51-8E65-4C7BD39105F4",
"versionEndExcluding": "9.17",
"versionStartIncluding": "9.13",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
]
}
],
"cveTags": [],
"descriptions": [
{
"lang": "en",
"value": "The fix for CVE-2026-12045 in pgAdmin 4 9.16 required the LLM-supplied query passed to the AI Assistant\u0027s execute_sql_query tool to parse, via sqlparse, as exactly one non-transaction-control statement before running it inside a BEGIN TRANSACTION READ ONLY wrapper. sqlparse\u0027s string-literal lexing can disagree with PostgreSQL\u0027s own parser: under standard_conforming_strings = on (PostgreSQL\u0027s default since 9.1), a backslash immediately before a quote is an ordinary character to PostgreSQL, but sqlparse treats it as escaping the quote. A payload such as SELECT \u0027\\\u0027;COMMIT;CREATE TABLE pwn(x int);SELECT 1 --\u0027 therefore parses as a single SELECT to sqlparse\u0027s validator, while PostgreSQL executes it as four statements: the smuggled COMMIT ends the wrapping read-only transaction, and the trailing ROLLBACK becomes a no-op. This reintroduces the same write/RCE bypass CVE-2026-12045 was meant to close, reachable via the same indirect prompt-injection delivery (an attacker plants the payload in any object the AI Assistant may read; the LLM emits it as a tool call).\n\nAn initial candidate fix ran the query with psycopg\u0027s execute(..., prepare=True), intending to force PostgreSQL\u0027s own Parse step (extended query protocol) to reject multi-statement text regardless of sqlparse\u0027s classification. This candidate fix does not work as submitted: psycopg3\u0027s PrepareManager silently ignores the prepare argument whenever the connection\u0027s prepare_threshold is None, which is pgAdmin\u0027s default for every server connection (the per-server \"Prepare threshold\" field is blank unless an administrator explicitly sets it) -- psycopg3 falls back to the simple query protocol, the same multi-statement-capable path the bypass exploits, so the candidate fix closes nothing on any real-world default configuration.\n\nThe corrected fix sets conn.prepare_threshold = 0 directly on the dedicated, single-use read-only connection the AI Assistant tool opens, structurally forcing the extended query protocol independent of any server-level configuration. Verified against a live PostgreSQL 18 instance: the payload executes successfully under the prepare_threshold=None (default) behavior, and is rejected with \"cannot insert multiple commands into a prepared statement\" once prepare_threshold=0 is set on that connection.\n\nThis issue affects pgAdmin 4: from 9.13 before 9.17."
},
{
"lang": "es",
"value": "La soluci\u00f3n para CVE-2026-12045 en pgAdmin 4 9.16 requer\u00eda que la consulta proporcionada por el LLM, pasada a la herramienta execute_sql_query del Asistente de IA, se analizara, a trav\u00e9s de sqlparse, como exactamente una declaraci\u00f3n que no fuera de control de transacciones antes de ejecutarla dentro de un envoltorio BEGIN TRANSACTION READ ONLY. El an\u00e1lisis l\u00e9xico de literales de cadena de sqlparse puede diferir del propio analizador de PostgreSQL: bajo standard_conforming_strings = on (el valor predeterminado de PostgreSQL desde la versi\u00f3n 9.1), una barra invertida inmediatamente antes de una comilla es un car\u00e1cter ordinario para PostgreSQL, pero sqlparse la trata como un escape de la comilla. Una carga \u00fatil como SELECT \u2019\\\u2019;COMMIT;CREATE TABLE pwn(x int);SELECT 1 --\u2019 por lo tanto, se analiza como un \u00fanico SELECT para el validador de sqlparse, mientras que PostgreSQL la ejecuta como cuatro declaraciones: el COMMIT introducido de contrabando finaliza la transacci\u00f3n de solo lectura envolvente, y el ROLLBACK final se convierte en una operaci\u00f3n nula. Esto reintroduce el mismo bypass de escritura/RCE que CVE-2026-12045 pretend\u00eda cerrar, alcanzable a trav\u00e9s de la misma entrega indirecta de inyecci\u00f3n de prompt (un atacante planta la carga \u00fatil en cualquier objeto que el Asistente de IA pueda leer; el LLM la emite como una llamada a herramienta).\n\nUna soluci\u00f3n candidata inicial ejecut\u00f3 la consulta con execute(..., prepare=True) de psycopg, con la intenci\u00f3n de forzar el propio paso de Parse de PostgreSQL (protocolo de consulta extendido) para rechazar texto con m\u00faltiples declaraciones independientemente de la clasificaci\u00f3n de sqlparse. Esta soluci\u00f3n candidata no funciona como se envi\u00f3: el PrepareManager de psycopg3 ignora silenciosamente el argumento prepare siempre que el prepare_threshold de la conexi\u00f3n es None, que es el valor predeterminado de pgAdmin para cada conexi\u00f3n de servidor (el campo \u2019Umbral de preparaci\u00f3n\u2019 por servidor est\u00e1 en blanco a menos que un administrador lo configure expl\u00edcitamente) -- psycopg3 recurre al protocolo de consulta simple, la misma ruta capaz de m\u00faltiples declaraciones que explota el bypass, por lo que la soluci\u00f3n candidata no cierra nada en ninguna configuraci\u00f3n predeterminada del mundo real.\n\nLa soluci\u00f3n corregida establece conn.prepare_threshold = 0 directamente en la conexi\u00f3n de solo lectura dedicada y de un solo uso que abre la herramienta del Asistente de IA, forzando estructuralmente el protocolo de consulta extendido independientemente de cualquier configuraci\u00f3n a nivel de servidor. Verificado contra una instancia activa de PostgreSQL 18: la carga \u00fatil se ejecuta correctamente bajo el comportamiento prepare_threshold=None (predeterminado), y es rechazada con \u2019cannot insert multiple commands into a prepared statement\u2019 una vez que prepare_threshold=0 se establece en esa conexi\u00f3n.\n\nEste problema afecta a pgAdmin 4: desde la versi\u00f3n 9.13 hasta antes de la 9.17."
}
],
"id": "CVE-2026-17351",
"lastModified": "2026-10-23T23:10:00.157",
"metrics": {
"cvssMetricV31": [
{
"cvssData": {
"attackComplexity": "LOW",
"attackVector": "NETWORK",
"availabilityImpact": "HIGH",
"baseScore": 9.0,
"baseSeverity": "CRITICAL",
"confidentialityImpact": "HIGH",
"integrityImpact": "HIGH",
"privilegesRequired": "LOW",
"scope": "CHANGED",
"userInteraction": "REQUIRED",
"vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H",
"version": "3.1"
},
"exploitabilityScore": 2.3,
"impactScore": 6.0,
"source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
"type": "Secondary"
},
{
"cvssData": {
"attackComplexity": "LOW",
"attackVector": "NETWORK",
"availabilityImpact": "HIGH",
"baseScore": 9.0,
"baseSeverity": "CRITICAL",
"confidentialityImpact": "HIGH",
"integrityImpact": "HIGH",
"privilegesRequired": "LOW",
"scope": "CHANGED",
"userInteraction": "REQUIRED",
"vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H",
"version": "3.1"
},
"exploitabilityScore": 2.3,
"impactScore": 6.0,
"source": "nvd@nist.gov",
"type": "Primary"
}
],
"cvssMetricV40": [
{
"cvssData": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "NONE",
"attackVector": "NETWORK",
"availabilityRequirement": "NOT_DEFINED",
"baseScore": 9.4,
"baseSeverity": "CRITICAL",
"confidentialityRequirement": "NOT_DEFINED",
"exploitMaturity": "NOT_DEFINED",
"integrityRequirement": "NOT_DEFINED",
"modifiedAttackComplexity": "NOT_DEFINED",
"modifiedAttackRequirements": "NOT_DEFINED",
"modifiedAttackVector": "NOT_DEFINED",
"modifiedPrivilegesRequired": "NOT_DEFINED",
"modifiedSubAvailabilityImpact": "NOT_DEFINED",
"modifiedSubConfidentialityImpact": "NOT_DEFINED",
"modifiedSubIntegrityImpact": "NOT_DEFINED",
"modifiedUserInteraction": "NOT_DEFINED",
"modifiedVulnAvailabilityImpact": "NOT_DEFINED",
"modifiedVulnConfidentialityImpact": "NOT_DEFINED",
"modifiedVulnIntegrityImpact": "NOT_DEFINED",
"privilegesRequired": "LOW",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "HIGH",
"subConfidentialityImpact": "HIGH",
"subIntegrityImpact": "HIGH",
"userInteraction": "PASSIVE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"version": "4.0",
"vulnAvailabilityImpact": "HIGH",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "HIGH",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
"type": "Secondary"
}
],
"ssvcV203": [
{
"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"ssvcData": {
"id": "CVE-2026-17351",
"options": [
{
"exploitation": "none"
},
{
"automatable": "no"
},
{
"technicalImpact": "total"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-07-31T00:00:00+00:00",
"version": "2.0.3"
}
}
]
},
"published": "2026-07-31T16:16:59.807",
"references": [
{
"source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
"tags": [
"Patch"
],
"url": "https://github.com/pgadmin-org/pgadmin4/commit/bf4792444446f0e7ab721d23cbd6bfe6afaa7a8b"
},
{
"source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
"tags": [
"Patch"
],
"url": "https://github.com/pgadmin-org/pgadmin4/commit/ef76102bcd1cdb544eb9b4ef18d3382f22b76752"
},
{
"source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
"tags": [
"Issue Tracking",
"Patch",
"Vendor Advisory"
],
"url": "https://github.com/pgadmin-org/pgadmin4/issues/10192"
}
],
"sourceIdentifier": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
"vulnStatus": "Analyzed",
"weaknesses": [
{
"description": [
{
"lang": "en",
"value": "CWE-89"
},
{
"lang": "en",
"value": "CWE-115"
}
],
"source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
"type": "Secondary"
}
]
}
},
"redhat_vex": {
"current_release_date": "2026-08-03T14:09:57+00:00",
"cve": "CVE-2026-17351",
"id": "CVE-2026-17351",
"initial_release_date": "2026-07-31T16:00:19.103000+00:00",
"product_status:known_not_affected": "1",
"source": "Red Hat CSAF VEX",
"status": "final",
"title": "pgadmin4: AI Assistant read-only transaction bypass via sqlparse/PostgreSQL lexer disagreement (incomplete fix for CVE-2026-12045)",
"url": "https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-17351.json",
"version": "3"
},
"vulnrichment": {
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-17351",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "total"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-07-31T17:00:07.232339Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-07-31T17:00:14.067Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"defaultStatus": "unaffected",
"modules": [
"AI Assistant",
"LLM Tools"
],
"product": "pgAdmin 4",
"programFiles": [
"https://github.com/pgadmin-org/pgadmin4/blob/master/web/pgadmin/llm/tools/database.py"
],
"repo": "https://github.com/pgadmin-org/pgadmin4",
"vendor": "pgadmin.org",
"versions": [
{
"lessThan": "9.17",
"status": "affected",
"version": "9.13",
"versionType": "custom"
}
]
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Kai Aizen (SnailSploit)"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Kundan Sable \u003ckundan.sable@enterprisedb.com\u003e"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Ashesh Vashi \u003cashesh.vashi@enterprisedb.com\u003e"
},
{
"lang": "en",
"type": "remediation reviewer",
"value": "Ashesh Vashi \u003cashesh.vashi@enterprisedb.com\u003e"
}
],
"descriptions": [
{
"lang": "en",
"value": "The fix for CVE-2026-12045 in pgAdmin 4 9.16 required the LLM-supplied query passed to the AI Assistant\u0027s execute_sql_query tool to parse, via sqlparse, as exactly one non-transaction-control statement before running it inside a BEGIN TRANSACTION READ ONLY wrapper. sqlparse\u0027s string-literal lexing can disagree with PostgreSQL\u0027s own parser: under standard_conforming_strings = on (PostgreSQL\u0027s default since 9.1), a backslash immediately before a quote is an ordinary character to PostgreSQL, but sqlparse treats it as escaping the quote. A payload such as SELECT \u0027\\\u0027;COMMIT;CREATE TABLE pwn(x int);SELECT 1 --\u0027 therefore parses as a single SELECT to sqlparse\u0027s validator, while PostgreSQL executes it as four statements: the smuggled COMMIT ends the wrapping read-only transaction, and the trailing ROLLBACK becomes a no-op. This reintroduces the same write/RCE bypass CVE-2026-12045 was meant to close, reachable via the same indirect prompt-injection delivery (an attacker plants the payload in any object the AI Assistant may read; the LLM emits it as a tool call).\n\nAn initial candidate fix ran the query with psycopg\u0027s execute(..., prepare=True), intending to force PostgreSQL\u0027s own Parse step (extended query protocol) to reject multi-statement text regardless of sqlparse\u0027s classification. This candidate fix does not work as submitted: psycopg3\u0027s PrepareManager silently ignores the prepare argument whenever the connection\u0027s prepare_threshold is None, which is pgAdmin\u0027s default for every server connection (the per-server \"Prepare threshold\" field is blank unless an administrator explicitly sets it) -- psycopg3 falls back to the simple query protocol, the same multi-statement-capable path the bypass exploits, so the candidate fix closes nothing on any real-world default configuration.\n\nThe corrected fix sets conn.prepare_threshold = 0 directly on the dedicated, single-use read-only connection the AI Assistant tool opens, structurally forcing the extended query protocol independent of any server-level configuration. Verified against a live PostgreSQL 18 instance: the payload executes successfully under the prepare_threshold=None (default) behavior, and is rejected with \"cannot insert multiple commands into a prepared statement\" once prepare_threshold=0 is set on that connection.\n\nThis issue affects pgAdmin 4: from 9.13 before 9.17."
}
],
"metrics": [
{
"cvssV3_1": {
"attackComplexity": "LOW",
"attackVector": "NETWORK",
"availabilityImpact": "HIGH",
"baseScore": 9,
"baseSeverity": "CRITICAL",
"confidentialityImpact": "HIGH",
"integrityImpact": "HIGH",
"privilegesRequired": "LOW",
"scope": "CHANGED",
"userInteraction": "REQUIRED",
"vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H",
"version": "3.1"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "Threat model: identical to CVE-2026-12045 -- indirect prompt injection. An attacker with low-privilege DB write access plants a payload in any object the AI Assistant might read (table row, column value, comment). When a pgAdmin user with a higher-privilege database role (typically superuser or holder of pg_execute_server_program) opens the AI Assistant against that content, the LLM emits the lexer-differential payload as a tool call, which smuggles a COMMIT past the intended read-only guard and can chain to COPY ... TO PROGRAM for OS code execution. Scored identically to the original CVE-2026-12045 record for consistency, since this is the same vulnerability surviving an incomplete fix rather than a functionally different bug: S:C for the confused-deputy pattern (attacker is not the LLM user; third-party DB content steers the user\u0027s own LLM session into unauthorised writes)."
}
]
},
{
"cvssV4_0": {
"baseScore": 9.4,
"baseSeverity": "CRITICAL",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H",
"version": "4.0"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "Same reasoning as the CVSS 3.1 entry and as the original CVE-2026-12045 record: indirect prompt injection, third-party content drives the user\u0027s LLM session, COPY ... TO PROGRAM reaches the DB host. VC:H/VI:H/VA:H + SC:H/SI:H/SA:H since RCE on the DB host compromises both pgAdmin\u0027s authority and the downstream system. UI:P captures that the user merely uses the AI Assistant normally."
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-89",
"description": "CWE-89 Improper Neutralization of Special Elements used in an SQL Command (\u0027SQL Injection\u0027)",
"lang": "en",
"type": "CWE"
},
{
"cweId": "CWE-115",
"description": "CWE-115 Misinterpretation of Input",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-07-31T16:00:19.103Z",
"orgId": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
"shortName": "PostgreSQL"
},
"references": [
{
"tags": [
"issue-tracking"
],
"url": "https://github.com/pgadmin-org/pgadmin4/issues/10192"
},
{
"tags": [
"patch"
],
"url": "https://github.com/pgadmin-org/pgadmin4/commit/ef76102bcd1cdb544eb9b4ef18d3382f22b76752"
},
{
"tags": [
"related"
],
"url": "https://github.com/pgadmin-org/pgadmin4/commit/bf4792444446f0e7ab721d23cbd6bfe6afaa7a8b"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "pgAdmin 4: AI Assistant read-only transaction bypass via sqlparse/PostgreSQL lexer disagreement (incomplete fix for CVE-2026-12045)"
}
},
"cveMetadata": {
"assignerOrgId": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
"assignerShortName": "PostgreSQL",
"cveId": "CVE-2026-17351",
"datePublished": "2026-07-31T16:00:19.103Z",
"dateReserved": "2026-07-25T02:52:57.350Z",
"dateUpdated": "2026-08-01T03:56:14.973Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
}
}
Loading…
Loading…
Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.
Experimental. This forecast is provided for visualization only and may change without notice. Do not use it for operational decisions.
Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline
Sightings and recorded dates, grouped by day · UTC
Loading timeline…
Loading…
Loading…
The MITRE ATT&CK techniques below are AI-generated suggestions, inferred from the description of the
vulnerability by the CIRCL/vulnerability-attack-technique-classification-roberta-base
model, served locally by ML-Gateway.
They have not been verified by an analyst and are provided for guidance only.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Loading…
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.