CVE-2026-12045
Full vulnerability record from the local CVENow database.
Description
Read-only transaction bypass in the pgAdmin 4 AI Assistant allows an attacker who can influence database content that the assistant reads to execute arbitrary SQL with the privileges of the pgAdmin user's database role. The AI Assistant's execute_sql_query tool runs LLM-generated SQL inside a BEGIN TRANSACTION READ ONLY wrapper to prevent data modification. The LLM-supplied query was forwarded to the database driver without restriction to a single statement or to read-only verbs, so a multi-statement payload beginning with COMMIT, END, ROLLBACK, or ABORT terminated the read-only transaction and ran subsequent statements in autocommit mode. The trailing ROLLBACK then had no effect. Delivery is via prompt injection: an attacker who can write content into any object the AI Assistant may inspect (a row, a column value, a comment) can cause the LLM to emit the multi-statement payload as a tool call. With ordinary write privileges on the pgAdmin user's role the attacker can perform unauthorised data modification. When the pgAdmin user's role is a PostgreSQL superuser or holds pg_execute_server_program, the chain extends to remote code execution on the database server host via COPY ... TO PROGRAM. Fix validates the LLM-supplied query up front: it must parse to exactly one non-empty / non-comment statement whose leading real token (after stripping whitespace, comments, and punctuation) is one of SELECT, WITH, EXPLAIN, SHOW, VALUES, or TABLE. Transaction-control verbs, DML, DDL, CALL, COPY, DO, SET/RESET, and everything else are rejected before any database work happens. PostgreSQL's READ ONLY mode continues to backstop data-modifying CTEs, EXPLAIN ANALYZE on writes, and volatile side effects. This issue affects pgAdmin 4: from 9.13 before 9.16.
View original CVE JSON
{
"id": "CVE-2026-12045",
"sourceIdentifier": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
"published": "2026-06-19T00:16:46.703",
"lastModified": "2026-10-25T23:10:00.167",
"vulnStatus": "Analyzed",
"cveTags": [],
"descriptions": [
{
"lang": "en",
"value": "Read-only transaction bypass in the pgAdmin 4 AI Assistant allows an attacker who can influence database content that the assistant reads to execute arbitrary SQL with the privileges of the pgAdmin user's database role.\n\nThe AI Assistant's execute_sql_query tool runs LLM-generated SQL inside a BEGIN TRANSACTION READ ONLY wrapper to prevent data modification. The LLM-supplied query was forwarded to the database driver without restriction to a single statement or to read-only verbs, so a multi-statement payload beginning with COMMIT, END, ROLLBACK, or ABORT terminated the read-only transaction and ran subsequent statements in autocommit mode. The trailing ROLLBACK then had no effect.\n\nDelivery is via prompt injection: an attacker who can write content into any object the AI Assistant may inspect (a row, a column value, a comment) can cause the LLM to emit the multi-statement payload as a tool call. With ordinary write privileges on the pgAdmin user's role the attacker can perform unauthorised data modification. When the pgAdmin user's role is a PostgreSQL superuser or holds pg_execute_server_program, the chain extends to remote code execution on the database server host via COPY ... TO PROGRAM.\n\nFix validates the LLM-supplied query up front: it must parse to exactly one non-empty / non-comment statement whose leading real token (after stripping whitespace, comments, and punctuation) is one of SELECT, WITH, EXPLAIN, SHOW, VALUES, or TABLE. Transaction-control verbs, DML, DDL, CALL, COPY, DO, SET/RESET, and everything else are rejected before any database work happens. PostgreSQL's READ ONLY mode continues to backstop data-modifying CTEs, EXPLAIN ANALYZE on writes, and volatile side effects.\n\nThis issue affects pgAdmin 4: from 9.13 before 9.16."
},
{
"lang": "es",
"value": "La omisión de transacción de solo lectura en el Asistente de IA de pgAdmin 4 permite a un atacante que puede influir en el contenido de la base de datos que el asistente lee ejecutar SQL arbitrario con los privilegios del rol de base de datos del usuario de pgAdmin.\n\nLa herramienta execute_sql_query del Asistente de IA ejecuta SQL generado por LLM dentro de un envoltorio BEGIN TRANSACTION READ ONLY para evitar la modificación de datos. La consulta proporcionada por el LLM fue reenviada al controlador de la base de datos sin restricción a una sola declaración o a verbos de solo lectura, por lo que una carga útil de múltiples declaraciones que comenzaba con COMMIT, END, ROLLBACK o ABORT terminaba la transacción de solo lectura y ejecutaba las declaraciones subsiguientes en modo de autocommit. El ROLLBACK final entonces no tenía efecto.\n\nLa entrega es a través de inyección de prompt: un atacante que puede escribir contenido en cualquier objeto que el Asistente de IA pueda inspeccionar (una fila, un valor de columna, un comentario) puede hacer que el LLM emita la carga útil de múltiples declaraciones como una llamada a herramienta. Con privilegios de escritura ordinarios en el rol del usuario de pgAdmin, el atacante puede realizar modificaciones de datos no autorizadas. Cuando el rol del usuario de pgAdmin es un superusuario de PostgreSQL o posee pg_execute_server_program, la cadena se extiende a la ejecución remota de código en el host del servidor de la base de datos a través de COPY ... TO PROGRAM.\n\nLa corrección valida la consulta proporcionada por el LLM de antemano: debe analizarse como exactamente una declaración no vacía / sin comentarios cuyo token real principal (después de eliminar espacios en blanco, comentarios y puntuación) es uno de SELECT, WITH, EXPLAIN, SHOW, VALUES o TABLE. Los verbos de control de transacciones, DML, DDL, CALL, COPY, DO, SET/RESET y todo lo demás son rechazados antes de que se realice cualquier trabajo en la base de datos. El modo READ ONLY de PostgreSQL continúa respaldando las CTE que modifican datos, EXPLAIN ANALYZE en escrituras y efectos secundarios volátiles.\n\nEste problema afecta a pgAdmin 4: desde 9.13 antes de 9.16."
}
],
"affected": [
{
"source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
"affectedData": [
{
"vendor": "pgadmin.org",
"product": "pgAdmin 4",
"defaultStatus": "unaffected",
"modules": [
"AI Assistant",
"LLM Tools"
],
"programFiles": [
"https://github.com/pgadmin-org/pgadmin4/blob/master/web/pgadmin/llm/tools/database.py"
],
"repo": "https://github.com/pgadmin-org/pgadmin4",
"versions": [
{
"version": "9.13",
"lessThan": "9.16",
"versionType": "custom",
"status": "affected"
}
]
}
]
}
],
"metrics": {
"cvssMetricV40": [
{
"source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
"type": "Secondary",
"cvssData": {
"version": "4.0",
"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",
"baseScore": 9.4,
"baseSeverity": "CRITICAL",
"attackVector": "NETWORK",
"attackComplexity": "LOW",
"attackRequirements": "NONE",
"privilegesRequired": "LOW",
"userInteraction": "PASSIVE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "HIGH",
"vulnAvailabilityImpact": "HIGH",
"subConfidentialityImpact": "HIGH",
"subIntegrityImpact": "HIGH",
"subAvailabilityImpact": "HIGH",
"exploitMaturity": "NOT_DEFINED",
"confidentialityRequirement": "NOT_DEFINED",
"integrityRequirement": "NOT_DEFINED",
"availabilityRequirement": "NOT_DEFINED",
"modifiedAttackVector": "NOT_DEFINED",
"modifiedAttackComplexity": "NOT_DEFINED",
"modifiedAttackRequirements": "NOT_DEFINED",
"modifiedPrivilegesRequired": "NOT_DEFINED",
"modifiedUserInteraction": "NOT_DEFINED",
"modifiedVulnConfidentialityImpact": "NOT_DEFINED",
"modifiedVulnIntegrityImpact": "NOT_DEFINED",
"modifiedVulnAvailabilityImpact": "NOT_DEFINED",
"modifiedSubConfidentialityImpact": "NOT_DEFINED",
"modifiedSubIntegrityImpact": "NOT_DEFINED",
"modifiedSubAvailabilityImpact": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"valueDensity": "NOT_DEFINED",
"vulnerabilityResponseEffort": "NOT_DEFINED",
"providerUrgency": "NOT_DEFINED"
}
}
],
"cvssMetricV31": [
{
"source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
"type": "Secondary",
"cvssData": {
"version": "3.1",
"vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H",
"baseScore": 9.0,
"baseSeverity": "CRITICAL",
"attackVector": "NETWORK",
"attackComplexity": "LOW",
"privilegesRequired": "LOW",
"userInteraction": "REQUIRED",
"scope": "CHANGED",
"confidentialityImpact": "HIGH",
"integrityImpact": "HIGH",
"availabilityImpact": "HIGH"
},
"exploitabilityScore": 2.3,
"impactScore": 6.0
},
{
"source": "[email protected]",
"type": "Primary",
"cvssData": {
"version": "3.1",
"vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"baseScore": 8.8,
"baseSeverity": "HIGH",
"attackVector": "NETWORK",
"attackComplexity": "LOW",
"privilegesRequired": "LOW",
"userInteraction": "NONE",
"scope": "UNCHANGED",
"confidentialityImpact": "HIGH",
"integrityImpact": "HIGH",
"availabilityImpact": "HIGH"
},
"exploitabilityScore": 2.8,
"impactScore": 5.9
}
],
"ssvcV203": [
{
"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"ssvcData": {
"timestamp": "2026-06-22T00:00:00+00:00",
"id": "CVE-2026-12045",
"options": [
{
"exploitation": "none"
},
{
"automatable": "no"
},
{
"technicalImpact": "total"
}
],
"role": "CISA Coordinator",
"version": "2.0.3"
}
}
]
},
"weaknesses": [
{
"source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
"type": "Secondary",
"description": [
{
"lang": "en",
"value": "CWE-77"
},
{
"lang": "en",
"value": "CWE-89"
}
]
}
],
"configurations": [
{
"nodes": [
{
"operator": "OR",
"negate": false,
"cpeMatch": [
{
"vulnerable": true,
"criteria": "cpe:2.3:a:pgadmin:pgadmin_4:*:*:*:*:*:postgresql:*:*",
"versionStartIncluding": "9.13",
"versionEndExcluding": "9.16",
"matchCriteriaId": "DF458F90-77B9-4602-8B5B-76408903E9FD"
}
]
}
]
}
],
"references": [
{
"url": "https://github.com/pgadmin-org/pgadmin4/commit/bf4792444446f0e7ab721d23cbd6bfe6afaa7a8b",
"source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
"tags": [
"Patch"
]
},
{
"url": "https://github.com/pgadmin-org/pgadmin4/issues/10022",
"source": "f86ef6dc-4d3a-42ad-8f28-e6d5547a5007",
"tags": [
"Issue Tracking",
"Patch",
"Third Party Advisory"
]
}
]
}