CVE-2026-12047Low· 3.5▾ SunlitHTML injection in pgAdmin 4's cloud deployment module. The verify_credentials, deploy, regions, and update-server endpoints under /rds/, /azure/, /google/, and the top-level /cloud/ blueprint propagated AWS / Azure / Google SDK exception…
▾ Sunlit zone — Low / medium · no exploitation signal
impact 19.3 · likelihood 0 · exploitation 0
Need a working PoC? Pro members can cast a request and our team develops one — it lands right here.
Exploit-prediction probability, daily snapshots since Jul 4.
Disclosure to exploitation, from the record and what we observed since indexing it.
Disclosed via NVD
Last analysed / modified upstream
0.1%
0.1% → 0.2%
HTML injection in pgAdmin 4's cloud deployment module. The verify_credentials, deploy, regions, and update-server endpoints under /rds/, /azure/, /google/, and the top-level /cloud/ blueprint propagated AWS / Azure / Google SDK exception text — and the related file-resolution and database-commit exception text — into the JSON response body (the info and errormsg fields) without HTML-encoding. The Cloud Wizard frontend rendered these strings through html-react-parser, so an attacker-influenced exception message embedded structural HTML directly into the wizard's DOM.
The reported entry point is /rds/verify_credentials/. An authenticated pgAdmin user submits a crafted access_key whose value contains an <iframe/src=...> payload; AWS STS rejects the credential with an IncompleteSignature exception whose text quotes the access_key verbatim; the pgAdmin backend forwards that text into the JSON info field; the Cloud Wizard's FormFooterMessage parses it as HTML. The browser fetches the iframe's src from an attacker-controlled host, and JavaScript executing inside the cross-origin iframe writes to parent.location, redirecting the victim's pgAdmin tab. Because the injection renders inside pgAdmin's own interface, X-Frame-Options and Content-Security-Policy frame-ancestors do not mitigate it. Baseline impact is self-targeted (the same user who supplied the payload sees the injection); escalation against other authenticated users requires an additional cross-site request-forgery primitive capable of submitting the malformed credential request with a valid X-pgA-CSRFToken in the victim's browser context.
The same unsanitised-error-into-JSON pattern was present across multiple sibling endpoints — Azure's check_cluster_name_availability, every Google endpoint that surfaces SDK errors (verification_ack, projects, regions, instance_types, database_versions, the verify_credentials path-resolution branches), the central /deploy endpoint that bubbles str(e) from deploy_on_rds / deploy_on_azure / deploy_on_google, and update_cloud_server which surfaces the str(e) from a failing db.session.commit — all of which are now covered.
Fix HTML-escapes every external/SDK exception string at the endpoint sink via a new shared sanitize_external_text helper (HTML escape with control-character strip), promoted out of the psycopg3 driver into web/pgadmin/utils/text_sanitize.py. The Cloud Wizard frontend additionally renders its FormFooterMessage in plain-text mode for backend-derived strings, so the value is never parsed as HTML even if a future sink forgets the escape.
This issue affects pgAdmin 4: from 6.6 before 9.16.
pgadmin_4 >= 6.6, < 9.16Upgrade past the affected range:
pgadmin_4 9.16Connected by shared product, vendor, weakness, or advisory.
CVE-2026-12048Critical· 9.3Stored cross-site scripting in pgAdmin 4's error-rendering and plan-node-rendering paths
CVE-2026-86862Medium· 6.5pgAdmin 4's Restore and Maintenance tools passed the client-supplied 'database' field directly as the value of the --dbname option given to pg_restore and psql
CVE-2026-86863Critical· 9.8pgAdmin 4's Webserver authentication source is intended to accept an identity asserted by the web server or reverse proxy in front of pgAdmin, delivered through the WSGI/CGI environment
CVE-2026-86864High· 8.8pgAdmin 4's Backup tool appended the client-supplied 'database' field from the /backup/job/<sid>/object request to the pg_dump argument vector as a bare trailing positional argument, without validation
CVE-2026-86861Medium· 5.9pgAdmin 4's File Manager save_file endpoint, which backs saving from the Query Tool and ERD, validated the requested path with Filemanager.check_access_permission() and then opened the file for writing with a plain open() call
CVE-2026-12050Medium· 4.3SQL injection in pgAdmin 4's named restore point endpoint (POST /browser/server/restore_point/{gid}/{sid})