CVE-2026-19634
Executive Summary
CVE-2026-19634 is a SQL injection vulnerability discovered in PostgreSQL Anonymizer, an extension designed to mask and anonymize sensitive data within PostgreSQL databases. The flaw exists in two import functions — anon.import_database_rules() and anon.import_roles_rules() — which fail to properly sanitize object names when parsing JSON documents. A malicious JSON payload containing specially crafted object names can trigger arbitrary SQL execution when a superuser imports the document, enabling privilege escalation to superuser-level access within the database environment.
The vulnerability carries a CVSS score of 6.4 (High), reflecting the high privileges required to exploit it combined with the severe confidentiality, integrity, and availability impact achieved upon successful exploitation. The vulnerability is confirmed fixed in PostgreSQL Anonymizer version 3.1.4 and later. Organizations running earlier versions of this extension — particularly those that grant non-superuser roles the ability to submit JSON rule files that administrators subsequently import — should treat this as a critical supply-chain and database security risk. No public exploit code or CISA KEV listing exists at the time of writing.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
PostgreSQL Anonymizer is an open-source extension that provides declarative data anonymization for PostgreSQL databases, allowing administrators to mask sensitive column data, apply substitution strategies, and manage anonymization rules across database schemas. The extension exposes functions used by superusers (database administrators) to programmatically import and export anonymization rules and role-based access configurations. Two of these functions constitute the vulnerable attack surface:
anon.import_database_rules()— imports anonymization rules for database schemas/tables from a structured document.anon.import_roles_rules()— imports role-based anonymization configuration from a structured document.
Vulnerability Mechanism — SQL Injection via Unsanitized Object Names:
The NVD description attributes the flaw to improper handling of object names embedded in JSON documents processed by these functions. When PostgreSQL Anonymizer parses an imported JSON document, it constructs SQL statements (likely CREATE, ALTER, or UPDATE operations) to store or apply the stated anonymization rules. Schema, table, column, and role names extracted from the JSON document are used in the construction of these SQL queries. If the extension builds these queries via string concatenation rather than using parameterized queries or PostgreSQL's quote_ident() function, a malicious object name can inject arbitrary SQL code.
For example, a JSON document containing a table or column descriptor such as {"table_name": "users; DROP TABLE important_data;--"} — or more subtly crafted injection strings using comment syntax (--) or stacked query separation — would result in the malicious SQL segment being appended to the otherwise legitimate query being executed by the import function. Because these functions are executed in the context of a superuser (pg_execute_server_program or similar elevated context), the injected payload inherits superuser privileges.
Attack Surface Analysis:
- Attack Vector: Network (the CVSS vector specifies
AV:N), although the actual exploitation path may be local or network-based depending on how the JSON import files reach the superuser. For example, if the extension has a web-accessible administrative panel that accepts JSON uploads, network attack feasibility increases. - Privilege Required: High (
PR:H). Successful exploitation depends on a superuser invoking the vulnerable import functions on attacker-crafted input. This suggests a layered attack model where the remote attacker first compromises or tricks a superuser into importing a malicious JSON document. - User Interaction Required: Yes (
UI:R). The attack is only successful when the superuser deliberately imports the malicious JSON file — the user interaction is the import action itself (file selection/upload). - Complexity: High (
AC:H). The attacker must construct a valid JSON file that passes schema validation yet still executes in the SQL injection context, a process that requires knowledge of the targeted table/role structures or repeated trial and error.
Exploitation Model:
The attack model resembles a "malicious file upload accepted by administrator" pattern. Because the attacker cannot directly invoke the import functions without superuser privileges, the attack depends on social engineering, a supply-chain compromise, or a secondary vulnerability that allows an attacker to introduce a crafted JSON document (e.g., via an application or web endpoint that writes files the DBA will later import). Once the JSON resets an object name containing malicious SQL constructs, any subsequent import action executes the injected payload.
Exploitation Scenarios
Note: No public PoC available; the attack chain below is inferred from vulnerability class and NVD description.
Step 1 — Reconnaissance and Target Identification: An attacker identifies a PostgreSQL deployment running PostgreSQL Anonymizer versions earlier than 3.1.4. Reconnaissance techniques include querying the database itself for the extension version (if database-level access is already compromised) or identifying the extension version through documentation, error messages, or package metadata if the attacker has host-level access. In a supply-chain context, the attacker may target a third-party tool or monitoring service that generates or routes anonymization rule files.
Step 2 — Triggering the Flaw (Malicious JSON Crafting): The attacker crafts a JSON document that mimics the legitimate format expected by the import functions. Within this document, object names (table names, role names, column names, schema names) encode SQL injection payloads. Since no public format samples exist in the provided intelligence, the payloads target the generic SQL injection class — using techniques such as:
- Stacked queries: breaking out of string literals to append separate SQL statements.
- Comment termination: using
--or/* */to negate trailing portions of the legitimate query. - Function chaining: exploiting PostgreSQL functions like
pg_sleep()for time-based oracle detection orcurrent_database()for value extraction.
The crafted JSON is delivered to the superuser through phishing, compromised tooling, or direct file injection.
Step 3 — Payload Execution (The Import):
The superuser, acting with legitimate administrative purpose, calls either anon.import_database_rules() or anon.import_roles_rules(), passing the crafted JSON file/document. During parsing, the extension constructs SQL statements using the attacker-controlled object names without proper sanitization. The injected SQL executes in the superuser's session context, inheriting all administrative privileges.
Step 4 — Post-Exploitation Impact: With superuser-level SQL execution, the attacker can:
- Create new superuser roles with known credentials, establishing persistence.
- Read sensitive data from all tables, bypassing the anonymization/masking rules, which defeats the extension's core security purpose.
- Modify, drop, or exfiltrate data — directly impacting data integrity and availability.
- Chain with PostgreSQL's
COPY ... PROGRAMorpg_read_file()to achieve host operating system-level command execution, extending the compromise beyond the database.
The extremely high impact on confidentiality, integrity, and availability (all rated High in the CVSS vector) underscores that this is not a simple information leak — successful exploitation grants full control over the database instance and potentially the underlying host.
Impact Assessment
Business Impact:
This vulnerability undermines the core security value proposition of PostgreSQL Anonymizer — the guarantee that sensitive data in non-production environments is properly masked. Successful exploitation gives an attacker superuser SQL access, which effectively bypasses all anonymization rules and exposes real production data (if the extension is used against production copies). For organizations subject to GDPR, HIPAA, PCI-DSS, or regional data protection regulations, a data breach resulting from this exploit carries regulatory fines, notification obligations, and reputational damage.
Systems Affected:
All PostgreSQL installations running PostgreSQL Anonymizer versions earlier than 3.1.4. Affected systems are those where this extension is installed and used — typically development, staging, and QA environments that maintain anonymized copies of production databases. Organizations using the extension's import mechanism in automated pipelines (CI/CD, data masking jobs scheduled via cron, or application-triggered imports) are most at risk, as those workflows may ingest JSON files from less trusted sources.
Blast Radius:
The CVSS vector (AV:N/AC:H/PR:H/UI:R/S:U/C:H/I:H/A:H) quantifies the impact as follows:
- Confidentiality: High — all data in the database readable, including columns that were supposed to be masked.
- Integrity: High — attacker can alter, inject, or delete data; can modify future JSON rule imports.
- Availability: High — can drop tables, shut down the database, or perform destructive operations.
- Scope: Unchanged — the compromise remains confined to the database instance and the extension's context, though host-level breakout via PostgreSQL's file/program functions is plausible in default configurations.
If the attacker achieves host-level command execution through chained PostgreSQL functionality (e.g., COPY ... PROGRAM), the blast radius may expand to the operating system account running PostgreSQL, potentially affecting other databases on the same server or coordinated via shared network infrastructure.
Detection Guidance
Sigma Rule
The following Sigma rule detects attempts to import suspicious JSON rule files or invocations of the import functions with unusual parameters (high-level database activity detection):
title: Suspicious PostgreSQL Anonymizer Import Activity
id: 5f4e7c3a-9de8-4b7a-8f2d-1b9e7a2f37aa
status: experimental
description: Detects invocation of anon.import_database_rules or anon.import_roles_rules with potential SQL injection indicators
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-19634
author: ValtersIT Threat Intelligence
date: 2026/01/15
logsource:
product: postgresql
category: database_query
detection:
selection_import:
query|contains:
- "anon.import_database_rules"
- "anon.import_roles_rules"
selection_injection_keywords:
query|contains:
- "';"
- "--"
- "/*"
- "pg_sleep"
- "current_database"
- "DROP TABLE"
condition: selection_import and selection_injection_keywords
timeframe: 5m
level: high
falsepositives:
- Legitimate imports that contain objects with special characters (rare)
- Admin scripts referencing these functions in documentation/comments
tags:
- attack.t1190
- cve.2026.19634
- cwe.89
YARA Rule
rule CVE_2026_19634_PostgresAnonymizer_JSON_IOC
{
meta:
author = "ValtersIT Threat Intelligence"
description = "Detect crafted JSON documents targeting anon.import_database_rules or anon.import_roles_rules"
cve = "CVE-2026-19634"
date = "2026-01-15"
severity = "high"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-19634"
strings:
$func1 = "import_database_rules" ascii nocase
$func2 = "import_roles_rules" ascii nocase
$obj_name = "\"table_name\"" ascii nocase
$obj_name2 = "\"column_name\"" ascii nocase
$obj_name3 = "\"schema_name\"" ascii nocase
$obj_name4 = "\"role_name\"" ascii nocase
$sql_break1 = "';" ascii
$sql_break2 = "';--" ascii
$sql_break3 = "\"';" ascii
$comment = "--" ascii
$drop = "drop table" ascii nocase
$sleep = "pg_sleep" ascii nocase
$exec = "pg_read_file" ascii nocase
$copy_prog = "copy" ascii nocase
condition:
uint16be(0) == 0x7B7B or uint32be(0) == 0x7B5C226E // { { or {\"n — JSON startup
and (any of ($func*) and any of ($obj_name*))
and (any of ($sql_break*) or any of ($comment, $drop, $sleep, $exec, $copy_prog))
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-19634 - PostgreSQL Anonymizer SQL Injection in JSON Import";
flow:established,to_server;
content:"import_database_rules"; http_client_body; nocase; sid:2026196341;
content:"import_roles_rules"; http_client_body; nocase; sid:2026196342;
content:"%;"; http_client_body; sid:2026196343;
content:"--"; http_client_body; sid:2026196344;
content:"pg_sleep"; http_client_body; nocase; sid:2026196345;
content:"=binary"; http_client_body; sid:2026196346;
reference:cve,2026-19634;
reference:url,https://nvd.nist.gov/vuln/detail/CVE-2026-19634;
classtype:attempted-admin;
priority:1;
metadata:created_at 2026_01_15, updated_at 2026_01_15;
rev:1;
)
Elastic Detection
// Elastic EQL rule: detect suspicious PostgreSQL Anonymizer JSON import content
sequence by process.pid
[file where event.action == "write" and
file.extension == "json" and file.name == "*.json" and
process.name : "*psql*" or process.name : "*pg_dump*"]
[file where event.action == "write" and process.name : "*psql*"
or process.name : "*python*" and
process.command_line : "*import_database_rules*"
or process.command_line : "*import_roles_rules*"]
[network where process.name : "*psql*" and destination.port == 5432]
Splunk SPL Query
index=postgresql sourcetype="postgresql:query"
("anon.import_database_rules" OR "anon.import_roles_rules")
(query_text="*;*" OR query_text="*--*" OR query_text="*/*"
OR query_text="*pg_sleep*" OR query_text="*current_database*"
OR query_text="*DROP TABLE*")
| eval threat_score = case(
match(query_text, "\';"), 80,
match(query_text, "\;--"), 90,
match(query_text, "pg_sleep"), 70,
match(query_text, "DROP TABLE"), 95,
1=1, 30
)
| where threat_score > 60
| table _time, user, db, query_text, src_ip, host
| sort - threat_score
Wazuh OSSEC Rule
<rule id="196341" level="15">
<if_sid>57100</if_sid>
<match>anon\.import_database_rules|anon\.import_roles_rules</match>
<regex>\;\s*--|/\*|pg_sleep|DROP TABLE|current_database</regex>
<group>postgresql,cve-2026-19634,attack.t1190,</group>
<description>Possible CVE-2026-19634 SQL injection attempt via PostgreSQL Anonymizer IMPORT functions</description>
<mitre>
<id>T1190</id>
</mitre>
<options>no_full_log</options>
</rule>
<rule id="196342" level="10">
<if_sid>196341</if_sid>
<user>postgres</user>
<description>CVE-2026-19634 exploitation attempt by postgres superuser</description>
</rule>
Mitigation & Patch Guidance
Patch Confidence: 0/4 — UNPATCHED — No evidence from any tracked source confirms the fix is available in PostgreSQL Anonymizer 3.1.4 beyond the NVD description's claim; validate against official PostgreSQL Anonymizer advisories before acting.
Immediate Mitigations:
- Upgrade PostgreSQL Anonymizer: The NVD description confirms version 3.1.4 fixes the issue. Test the upgrade in a staging environment first, as the patch may alter JSON import schema expectations.
- Restrict Import Function Access: Revoke
EXECUTEprivilege for theanon.import_database_rules()andanon.import_roles_rules()functions from all roles except those strictly required. UseREVOKE EXECUTE ON FUNCTION anon.import_database_rules(json) FROM PUBLIC;and re-grant only to trusted DBAs. - Validate JSON Sources: Implement strict source validation — JSON files must originate from trusted, known paths/URLs. Use secure (e.g., SHA-256) file integrity checks before them being passed to import functions.
- Superuser Awareness Training: Educate superusers on the risk of opening untrusted JSON content, emphasizing that these import functions should never ingest files from external or low-trust sources.
- If upgrade is not immediately possible, consider temporarily blocking HTTP/file upload endpoints that route to the import functions and/or disabling these functions with
ALTER FUNCTION ... UNLINKuntil the patch is deployed.
Patch/Upgrade Steps:
- Verify current extension version:
\dx anon; - Back up database schema and current PostgreSQL Anonymizer rule files.
- Download PostgreSQL Anonymizer 3.1.4 (or later) and follow the project's standard upgrade instructions (
ALTER EXTENSION anon UPDATE;is not sufficient — the extension must be updated in the package manager or via source build depending on installation method). - Re-run the import functions with clean test files to validate backward compatibility.
- Monitor PostgreSQL logs for abnormal activity immediately after the upgrade.
Long-Term Hardening:
- Adopt Parameterized Query Practices: Contribute to/audit the PostgreSQL Anonymizer codebase to ensure all dynamic SQL uses
quote_ident()or parameterized queries. - Implement Database Activity Monitoring: Use the Sigma/Elastic/Splunk rules provided to create continuous auditing for attempted exploitation.
- Principle of Least Privilege (PoLP): Ensure only designated superusers can invoke import functions, and consider running routine anonymizer imports from a separate, dedicated low-privilege role that has narrowly scoped access — a step that reduces exploit impact from full superuser to limited role capabilities.
- Input Validation Framework: Establish mandatory JSON schema validation for all import functionality, strictly enforcing allowed character sets for object names (restrict to a whitelist such as
[a-zA-Z0-9_]{1,63}) before processing. - Maintain Extension Update Discipline: Subscribe to PostgreSQL Anonymizer security advisories to minimize the window between patch release and deployment.
- Evaluate Alternative Masking Approaches: For critical production use cases, evaluate whether PostgreSQL Anonymizer is the most secure masking solution and maintain fallback strategies (e.g., commercial masking tools with a more mature security response posture).
References
- NVD Entry — https://nvd.nist.gov/vuln/detail/CVE-2026-19634
- PostgreSQL Anonymizer Official GitHub Repository — https://gitlab.com/dalibo/postgresql_anonymizer
- CWE-89 — Improper Neutralization of Special Elements used in an SQL Command — https://cwe.mitre.org/data/definitions/89.html
- PostgreSQL Security Advisories — https://www.postgresql.org/support/security/
- CISA Known Exploited Vulnerabilities (KEV) Catalog — https://www.cisa.gov/known-exploited-vulnerabilities-catalog
No known threat actor campaigns have been publicly attributed to this vulnerability as of this report. No exploit-in-the-wild evidence has been observed. CISA KEV does not currently list this CVE.