CVE-2026-12044
Received Received - Intake
SQL Injection in pgAdmin 4

Publication date: 2026-06-19

Last updated on: 2026-06-19

Assigner: PostgreSQL

Description
SQL injection in pgAdmin 4 across every dialog template that renders ``COMMENT ON ... IS '<description>'`` for a user-supplied description field. The Jinja templates for Domains (and their constraints), Foreign Tables, Languages, and Event Triggers, plus the Views OID-lookup query, interpolated the description directly inside a single-quoted SQL literal -- ``'{{ data.description }}'`` -- instead of passing it through the ``qtLiteral`` escape filter. An authenticated pgAdmin user with permission to create or alter the affected object types could submit a description containing an apostrophe, break out of the literal and chain arbitrary SQL. The injected SQL runs under the PostgreSQL role the user is already authenticated as; for a connected role with ``COPY ... TO/FROM PROGRAM`` (typically PostgreSQL superuser), this chains to OS command execution on the PostgreSQL host. The defect does not cross a privilege boundary -- the user already has direct SQL access to that role through pgAdmin's Query Tool -- so the attacker gains no capability beyond what their database role already grants. The marginal impact captures bypass of any application-layer Query Tool gating an operator may have configured. The defect was originally reported against the Domain Dialog ``description`` field; a code-wide audit identified sixteen sites of the same pattern across the templates listed above. The same review also surfaced ten related sinks in the pgstattuple/pgstatindex stats templates -- ``pgstattuple('{{schema}}.{{table}}')`` and the matching pgstatindex shape -- where ``qtIdent`` escapes embedded double quotes inside the identifier but not apostrophes, so a user with CREATE privilege on a schema could plant a table or index named ``foo'bar`` and a later stats viewer would render an unbalanced literal. Fix is layered: 1. Sites: replace every ``'{{ x.description }}'`` with ``{{ x.description|qtLiteral(conn) }}`` (no surrounding quotes -- the filter wraps the value in escaped quotes itself). Plumb ``conn=self.conn`` through every ``render_template`` call that loads one of these templates. Also corrects a ``{ % elif`` Jinja typo in the foreign-table schema diff (dead branch). Rewrite the ten pgstattuple/pgstatindex stats sites to address the relation via OID + ``::oid::regclass`` cast (e.g. ``pgstattuple({{ tid }}::oid::regclass)``), eliminating the embedded literal-call form entirely so that bug-class can no longer recur there. 2. Driver hardening: ``qtLiteral`` (in ``utils/driver/psycopg3/__init__.py``) used to silently return the raw unescaped value when its ``conn`` argument was falsy. It now raises ``ValueError`` -- surfacing the entire bug class going forward. The change immediately uncovered eight latent plumbing bugs (in ``schemas/__init__.py``, ``schemas/functions/__init__.py``, ``schemas/tables/utils.py``, ``foreign_servers/__init__.py``, and seven sites in ``roles/__init__.py``) -- all fixed as part of this patch. The inner ``except`` block that swallowed adapter-level failures and returned the raw value is also removed, so unadaptable inputs raise instead of leaking unescaped values. 3. Regression tests: a per-template behavioural test renders each previously-vulnerable template with an apostrophe-injection payload and asserts the escaped fragment is present and the vulnerable fragment absent; a lint test walks every ``*.sql`` template flagging any ``'{{ ... }}'`` single-quote-wrapped interpolation against an explicit allowlist; unit tests cover the new qtLiteral fail-fast and inner-except raise paths. This issue affects pgAdmin 4: from 1.0 before 9.16.
CVSS Scores
EPSS Scores
Probability:
Percentile:
Meta Information
Published
2026-06-19
Last Modified
2026-06-19
Generated
2026-06-19
AI Q&A
2026-06-19
EPSS Evaluated
N/A
NVD
EUVD
Affected Vendors & Products
Showing 1 associated CPE
Vendor Product Version / Range
pgadmin pgadmin_4 From 1.0 (inc) to 9.16 (exc)
Helpful Resources
Exploitability
CWE
CWE Icon
KEV
KEV Icon
CWE ID Description
CWE-116 The product prepares a structured message for communication with another component, but encoding or escaping of the data is either missing or done incorrectly. As a result, the intended structure of the message is not preserved.
CWE-89 The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.
Attack-Flow Graph
AI Quick Actions
Instant insights powered by AI
Executive Summary

This vulnerability is a SQL injection issue in pgAdmin 4 affecting multiple dialog templates that render user-supplied description fields inside SQL COMMENT statements. The templates interpolated the description directly inside single-quoted SQL literals without proper escaping, allowing an authenticated user with permission to create or alter certain database objects to inject malicious SQL by including an apostrophe in the description. This injection runs with the same database role as the user, potentially allowing execution of arbitrary SQL commands and, for superusers, even OS command execution on the PostgreSQL host.

The vulnerability was found in 16 template sites and related stats templates, where improper escaping of identifiers could also lead to injection. The fix involved replacing unsafe string interpolation with a proper escaping filter (qtLiteral), hardening the driver to prevent silent failures, and adding regression tests to ensure the vulnerability is mitigated.

Impact Analysis

If exploited, this vulnerability allows an authenticated pgAdmin user with certain permissions to execute arbitrary SQL commands within the database under their own role. This could lead to unauthorized data manipulation or disclosure within the scope of their database privileges.

For users connected with a superuser role that has the PostgreSQL COPY ... TO/FROM PROGRAM capability, the injection can escalate to executing arbitrary OS commands on the database host, posing a severe security risk.

However, the vulnerability does not allow privilege escalation beyond the user's existing database role, but it can bypass application-layer query restrictions configured in pgAdmin's Query Tool.

Detection Guidance

Detection of this SQL injection vulnerability involves identifying attempts to inject apostrophes or other SQL control characters into description fields within pgAdmin 4 dialogs that render SQL COMMENT statements.

Since the vulnerability occurs when an authenticated user submits a description containing an apostrophe that breaks out of a single-quoted SQL literal, monitoring database logs or pgAdmin audit logs for unusual or malformed COMMENT ON ... IS '<description>' queries containing unescaped apostrophes or suspicious SQL fragments can help detect exploitation attempts.

Specific commands to detect this vulnerability are not provided in the available resources.

Mitigation Strategies

Immediate mitigation steps include upgrading pgAdmin 4 to version 9.16 or later, where the vulnerability CVE-2026-12044 has been fixed.

  • Apply the patch that replaces all vulnerable template interpolations of description fields with the safe qtLiteral escape filter, which properly escapes user input in SQL literals.
  • Ensure that the qtLiteral function is hardened to raise errors on missing connection objects, preventing silent failures that could allow unescaped values.
  • Verify that regression tests and linting are in place to prevent reintroduction of this class of SQL injection vulnerabilities.

Additionally, restrict permissions so that only trusted authenticated users have the ability to create or alter affected object types in pgAdmin 4.

Compliance Impact

This vulnerability is a SQL injection issue in pgAdmin 4 that allows an authenticated user with certain permissions to inject arbitrary SQL code. While the vulnerability does not escalate privileges beyond the user's existing database role, it could lead to unauthorized data access or manipulation within the scope of that role.

Such unauthorized data access or manipulation could potentially impact compliance with data protection standards and regulations like GDPR or HIPAA, which require strict controls over data confidentiality, integrity, and access. If an attacker exploits this vulnerability to access or alter sensitive personal or health data, it could result in violations of these regulations.

However, since the vulnerability does not cross privilege boundaries and requires authenticated access with specific permissions, the risk is somewhat mitigated by existing access controls. Organizations should ensure that only trusted users have the necessary permissions and that pgAdmin 4 is updated to a fixed version to prevent exploitation.

Chat Assistant
Ask questions about this CVE
Hi! I’m here to help you understand CVE-2026-12044. Ask me anything about the vulnerability, its impact, or mitigation strategies.
0/70
EPSS Chart