Summary
CVE-2026-12046 is a critical vulnerability in pgAdmin 4 (server mode) combining missing authentication on a critical function (CWE-306) with unsafe Python pickle deserialization (CWE-502), affecting all releases from version 6.9 up to, but not including, 9.16. Two SQL Editor endpoints were the only routes in the module lacking the @pga_login_required decorator, making them reachable by unauthenticated HTTP requests that flow directly into a pickle.loads deserialization sink. When additional attacker-controlled preconditions are satisfied, this flaw can be leveraged to achieve remote code execution on the host running pgAdmin. pgAdmin 4 version 9.16, released June 18, 2026, contains the fix.
Technical details
- Root cause: Two SQL Editor blueprint endpoints —
DELETE /sqleditor/close/<trans_id>andPOST /sqleditor/initialize/sqleditor/update_connection/<sgid>/<sid>/<did>— were the only routes in the SQL Editor module missing the@pga_login_requireddecorator. In server mode, this meant both endpoints could be exercised without any authenticated pgAdmin session. - Deserialization sink: Both endpoints reach a
pickle.loadscall operating onsession['gridData'][<trans_id>]['command_obj']— viaclose_sqleditor_session()andcheck_transaction_status()respectively. An attacker-supplied pickle payload at that location can deserialize into arbitrary Python objects, enabling code execution within the pgAdmin process. - Attack vector: Remote, over HTTP/HTTPS. No credentials or prior authentication are required to reach the vulnerable endpoints.
- Exploitation preconditions: Achieving full RCE also requires the attacker to possess (a) knowledge of the application’s Flask
SECRET_KEY, and (b) write access to pgAdmin’ssessions/directory on the host. Neither precondition is granted by this defect on its own; they must be obtained through a separate channel such as an exposed configuration file, a misconfigured deployment, or a prior partial compromise. The CVSS High Attack Complexity (AC:H) reflects these requirements. - Impact when preconditions are met: The missing authentication gate is the final step that elevates an existing partial compromise to unauthenticated code execution in the pgAdmin process and, by extension, on the host under the account running pgAdmin. The CVSS Scope is Changed (S:C), indicating the impact extends beyond the pgAdmin application boundary.
- Desktop mode unaffected: The vulnerability is server mode only. In Desktop mode, pgAdmin’s
before_requesthook re-authenticatesDESKTOP_USERon every request, so no endpoint can be exercised unauthenticated regardless of decorator presence. - Fix: Addition of the
@pga_login_requireddecorator to each of the two affected endpoints inweb/pgadmin/tools/sqleditor/__init__.py, ensuring the authentication and MFA chain executes before any session data is accessed or deserialized.
Affected software
- pgAdmin 4 versions 6.9 through 9.15 (all releases from 6.9 up to, but not including, 9.16)
Severity
- CVSS v3.1 Base Score: 9.0 (Critical)
- Vector string:
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H - CWE-306: Missing Authentication for Critical Function
- CWE-502: Deserialization of Untrusted Data
Mitigation and recommended actions
- Immediate: Upgrade to pgAdmin 4 version 9.16 (released June 18, 2026), which applies the
@pga_login_requireddecorator to both affected SQL Editor endpoints. - If immediate patching is not feasible: Restrict network-level access to the pgAdmin 4 server interface so it is not reachable from untrusted or public networks. pgAdmin 4 server mode should never be directly internet-exposed without a strict access control layer in front of it.
- Additional hardening: Ensure the Flask
SECRET_KEYis set to a strong, unique, non-default value and is not stored in any location accessible to unauthorized parties, as exposure of that key is one of the preconditions for full exploit.
IONIX Status
The IONIX research team is tracking ongoing exploitation attempts and recommends immediate patching. Potentially affected assets are outlined in this post.

