Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-13455

CVE-2026-13455: PostgreSQL Anonymizer Info Disclosure

CVE-2026-13455 is an information disclosure vulnerability in PostgreSQL Anonymizer that allows unprivileged users to perform offline brute-force attacks. This post covers technical details, affected versions, and mitigation.

Published:

CVE-2026-13455 Overview

CVE-2026-13455 affects PostgreSQL Anonymizer, an extension used to mask sensitive data in PostgreSQL databases. The vulnerability allows unprivileged masked users to repeatedly invoke the anon.hash() function and collect (seed, hash_output) pairs. Attackers can use these pairs to perform an offline brute-force attack and recover the secret salt. Once the salt is known, previously masked values become reversible, undermining the confidentiality guarantees of the anonymization layer. The issue is classified under [CWE-328] Use of Weak Hash. PostgreSQL Anonymizer versions prior to 3.1.2 are affected.

Critical Impact

Any authenticated database user with masked access can collect hash outputs, recover the salt offline, and reverse anonymized data — defeating the extension's core privacy control.

Affected Products

  • PostgreSQL Anonymizer versions prior to 3.1.2
  • PostgreSQL deployments using the anon extension for data masking
  • Environments exposing anon.hash() to unprivileged or masked roles

Discovery Timeline

  • 2026-06-30 - CVE-2026-13455 published to NVD
  • 2026-07-01 - Last updated in NVD database

Technical Details for CVE-2026-13455

Vulnerability Analysis

PostgreSQL Anonymizer provides the anon.hash() function so administrators can produce deterministic, salted hashes of sensitive values. The function relies on a secret salt to prevent attackers from correlating hashed outputs back to their original plaintext. In vulnerable versions, unprivileged masked users retain the ability to call anon.hash() directly and supply attacker-chosen seed values.

This exposes an oracle. An attacker submits many known inputs, records the resulting hashes, and builds a set of (seed, hash_output) pairs. With enough pairs, the attacker performs an offline brute-force search across candidate salts until the reproduced hashes match. Once the salt is recovered, every hashed column in the database becomes reversible through dictionary or rainbow-table attacks against the known plaintext space.

The root problem is a cryptographic design weakness rather than a memory-safety bug. The confidentiality of masked data depends entirely on salt secrecy, yet the function's access model lets the same untrusted users query the primitive that reveals it.

Root Cause

The root cause is improper protection of a cryptographic secret. The anon.hash() function is callable by roles that should only observe masked data, and its output is deterministic with respect to the hidden salt. This mirrors classic weak-hash issues covered by [CWE-328], where the algorithm or its parameters do not resist offline recovery.

Attack Vector

Exploitation requires network-reachable database access with low-privilege credentials. No user interaction is required. The attacker connects to the PostgreSQL instance, calls anon.hash() repeatedly with controlled seeds, exports the pairs, and runs an offline brute-force job against the salt space. Successful recovery yields the salt used across all masked columns in the deployment.

No public proof-of-concept or in-the-wild exploitation has been reported. See the GitLab Issue Discussion for maintainer details.

Detection Methods for CVE-2026-13455

Indicators of Compromise

  • Unusual volumes of anon.hash() calls originating from low-privilege or masked roles
  • Repeated calls with sequentially varied seed inputs from a single session or role
  • Large result sets or client-side exports containing hash outputs paired with attacker-supplied inputs
  • Long-running sessions from application accounts that normally only issue SELECT statements against masked views

Detection Strategies

  • Enable PostgreSQL statement logging (log_statement = 'all') for roles subject to masking and search for anon.hash( invocations.
  • Deploy a pg_stat_statements review to flag any role calling anon.hash() outside of administrative maintenance windows.
  • Correlate database audit logs with application identity to identify direct function calls that bypass expected query patterns.

Monitoring Recommendations

  • Baseline the expected callers of anon.* functions and alert on any new caller identity.
  • Forward PostgreSQL audit logs (pgaudit) to a centralized SIEM and build detections for high-frequency anon.hash() calls.
  • Monitor for bulk result exports from masked schemas, especially rows containing hash values alongside user-controlled seed columns.

How to Mitigate CVE-2026-13455

Immediate Actions Required

  • Upgrade PostgreSQL Anonymizer to version 3.1.2 or later on all affected instances.
  • Rotate the anonymization salt after upgrading so any previously leaked salt becomes worthless.
  • Revoke EXECUTE on anon.hash() from masked and application roles that do not require it.
  • Audit historical logs for prior abuse of anon.hash() by non-administrative accounts.

Patch Information

The maintainers fixed the issue in PostgreSQL Anonymizer 3.1.2. Refer to the GitLab Issue Discussion for the upstream fix details and upgrade guidance.

Workarounds

  • Restrict execution of anon.hash() to trusted administrative roles using REVOKE EXECUTE ON FUNCTION anon.hash(...) FROM PUBLIC;.
  • Replace direct hashing with pre-computed masked views so untrusted roles never call the hashing primitive.
  • Rotate the salt on a scheduled basis to limit the value of any single successful brute-force run.
  • Enforce least-privilege connection policies so only vetted application service accounts can reach the database.
bash
# Configuration example: restrict anon.hash() to a trusted role
REVOKE EXECUTE ON FUNCTION anon.hash(text) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION anon.hash(text) TO anon_admin;

# Rotate the salt after upgrading to 3.1.2 or later
ALTER DATABASE mydb SET anon.salt = 'new-high-entropy-secret';
SELECT anon.init();

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.