CVE-2026-17346

Source
https://cve.org/CVERecord?id=CVE-2026-17346
Import Source
https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-17346.json
JSON Data
https://api.osv.dev/v1/vulns/CVE-2026-17346
Published
2026-07-31T15:59:13.136Z
Modified
2026-08-02T03:45:59.558313391Z
Severity
  • 8.7 (High) CVSS_V4 - CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N CVSS Calculator
Summary
pgAdmin 4: SQL injection via unescaped object names in index Statistics and publication/subscription dependency views (incomplete fix for CVE-2026-12044)
Details

The fix for CVE-2026-12044 in pgAdmin 4 9.16 hardened qtLiteral and switched sixteen COMMENT ON / pgstattuple / pgstatindex templates to it, but missed several sinks that had been placed in testsqlstringliterallint.py's ALLOWLIST on the incorrect assumption that schema, table, publication, and subscription names sourced from pg_catalog via the browser tree could never contain an apostrophe. PostgreSQL permits arbitrary characters in quoted identifiers, so a low-privileged user able to CREATE TABLE, CREATE PUBLICATION, or CREATE SUBSCRIPTION can plant an apostrophe'd object name that breaks out of the unescaped '{{ name }}' template interpolation the moment any user (including a higher-privileged one) opens that object's Statistics or Dependencies tab, allowing arbitrary SQL statement injection in the viewing user's database session.

Affected sinks: the Index Statistics query for all-indexes listing (collstats.sql, both the 16plus and default PostgreSQL-version template variants -- distinct from the single-index stats.sql path already fixed in CVE-2026-12044), and the publication and subscription dependencies.sql / get_position.sql templates (both the pg and ppas/EPAS dialect variants for publications).

Fix switches all of these templates to qtLiteral(conn) for name interpolation, and updates publications/init.py and subscriptions/init.py to pass conn=self.conn into the dependencies.sql rendertemplate call so the qtLiteral filter has a connection to quote against. The corresponding ALLOWLIST entries in testsqlstringliteral_lint.py are removed now that these sinks are properly escaped rather than merely assumed safe. A behavioral regression test renders each fixed template with a stacked-statement apostrophe payload and asserts both that the object name appears exactly as qtLiteral-escaped and that the rendered SQL parses as exactly one statement, verifying the assertion genuinely fails against the pre-patch raw-interpolation form.

This issue affects pgAdmin 4: the Index Statistics sink from 1.0, and the Publications/Subscriptions sinks from 5.0, both before 9.17.

Database specific
{
    "cwe_ids": [
        "CWE-89"
    ],
    "osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/17xxx/CVE-2026-17346.json",
    "cna_assigner": "PostgreSQL",
    "unresolved_ranges": [
        {
            "source": "AFFECTED_FIELD",
            "extracted_events": [
                {
                    "introduced": "1.0"
                },
                {
                    "fixed": "9.17"
                },
                {
                    "introduced": "5.0"
                },
                {
                    "fixed": "9.17"
                }
            ]
        },
        {
            "source": "DESCRIPTION",
            "extracted_events": [
                {
                    "fixed": "9.17"
                }
            ]
        }
    ]
}
References

Affected packages

Git / github.com/pgadmin-org/pgadmin4

Affected ranges

Type
GIT
Repo
https://github.com/pgadmin-org/pgadmin4
Events
Introduced
0 Unknown introduced commit / All previous commits are affected
Fixed
Fixed
Database specific
{
    "source": "REFERENCES"
}

Affected versions

Other
REL-1_0
REL-1_0-BETA1
REL-1_0-BETA2
REL-1_0-BETA3
REL-1_0-BETA4
REL-1_0-RC1
REL-1_1
REL-1_2
REL-1_3
REL-1_4
REL-1_5
REL-1_6
REL-2_0
REL-2_0-RC1
REL-2_0-RC2
REL-2_1
REL-3_0
REL-3_1
REL-3_2
REL-3_3
REL-3_4
REL-3_5
REL-3_6
REL-4_0
REL-4_1
REL-4_10
REL-4_11
REL-4_12
REL-4_13
REL-4_14
REL-4_15
REL-4_16
REL-4_17
REL-4_18
REL-4_19
REL-4_2
REL-4_20
REL-4_21
REL-4_22
REL-4_23
REL-4_24
REL-4_25
REL-4_26
REL-4_27
REL-4_28
REL-4_29
REL-4_3
REL-4_30
REL-4_4
REL-4_5
REL-4_6
REL-4_7
REL-4_8
REL-4_9
REL-5_0
REL-5_1
REL-5_2
REL-5_3
REL-5_4
REL-5_5
REL-5_6
REL-5_7
REL-6_0
REL-6_1
REL-6_10
REL-6_11
REL-6_12
REL-6_13
REL-6_14
REL-6_15
REL-6_16
REL-6_17
REL-6_18
REL-6_19
REL-6_2
REL-6_20
REL-6_21
REL-6_3
REL-6_4
REL-6_5
REL-6_6
REL-6_7
REL-6_8
REL-6_9
REL-7_0
REL-7_1
REL-7_2
REL-7_3
REL-7_4
REL-7_5
REL-7_6
REL-7_7
REL-7_8
REL-8_0
REL-8_1
REL-8_10
REL-8_11
REL-8_12
REL-8_13
REL-8_14
REL-8_2
REL-8_3
REL-8_4
REL-8_5
REL-8_6
REL-8_7
REL-8_8
REL-8_9
REL-9_0
REL-9_1
REL-9_10
REL-9_11
REL-9_12
REL-9_13
REL-9_14
REL-9_15
REL-9_16
REL-9_2
REL-9_3
REL-9_4
REL-9_5
REL-9_6
REL-9_7
REL-9_8
REL-9_9

Database specific

source
"https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-17346.json"