When the SIEM Hands Out RCE: Splunk Enterprise CVE-2026-20253 Is a Pre-Auth File Write Through the PostgreSQL Sidecar
What we keep coming back to this week is how thoroughly this bug inverts the usual blue-team picture. Splunk Enterprise is the room with the cameras, the one your SOC walks into to look at everything else. CVE-2026-20253, the CVSS 9.8 pre-auth flaw Splunk patched on June 10, lets anyone on the network walk through a side door, run code as the Splunk user, and start editing the recording. Help Net Security confirmed in-the-wild exploitation on June 18, six days after a public PoC; CISA added the CVE to KEV the same day with a June 21 federal remediation deadline.
A CVSS 9.8 in a popular product is a normal Tuesday. What stopped us was where this bug sits and how ordinary the broken thing turns out to be: a small helper service nobody at most SOCs has heard of, doing nothing more exotic than calling pg_dump on behalf of an HTTP endpoint, hands pre-auth RCE to anything that can reach the host. If your mental model of Splunk's attack surface was "splunkd and the web UI," it just gained a footnote.
Where the Auth Check Went Missing
CVE-2026-20253 is a classic confused deputy. Splunk ships a PostgreSQL sidecar service to back up and restore the state used by Edge Processor and the newer SPL2 data pipelines, and behind it sits the local PostgreSQL instance the sidecar manages. The sidecar exposes an HTTP API that performs no authentication of its own and forwards whatever credentials it receives straight to pg_dump and pg_restore through the -U argument, trusting PostgreSQL to enforce auth, while PostgreSQL trusts that anything reaching the sidecar must already have been authorized upstream. Neither end checks, so a caller who reaches the sidecar inherits the database's trust for free. The watchTowr Labs writeup is titled "Why Use App-Level Auth When Every Database Has Auth?", which captures the design assumption that broke.
Tracing the Pre-Auth Chain to Code Execution
The sidecar listens on the local machine on port 5435, which sounds safe until you account for the __raw proxy path that splunkd's web tier exposes to forward requests through to internal services. Per the CyberSecurityNews breakdown of the chain, attackers reach the sidecar from the public Splunk web server via a path like /en-US/splunkd/__raw/v1/postgres/recovery/backup or its /restore sibling. They send a Basic auth header containing anything they like, including empty credentials, and the sidecar forwards that string into pg_dump or pg_restore as the database username.
That gets them a file-write primitive. The connection-string parsing in pg_dump lets the attacker inject parameters such as hostaddr=, port=, dbname=, and passfile=, so the dump can be sourced from a PostgreSQL server they control. The primitive becomes code execution through a built-in PostgreSQL function called lo_export, which writes a Large Object (a binary blob inside the database) to any path the database process can reach. The attacker imports a malicious dump whose Large Object payload is an attacker-controlled script, then calls lo_export to overwrite an internal Splunk script that runs on a schedule. When that script next fires, the payload runs as the Splunk service account.
The whole chain works because the sidecar is, at heart, an unauthenticated wrapper around two binaries that were never meant to be reachable across a network boundary. There is no memory corruption, no gadget chain, and no parser quirk, only a management endpoint that forgot to check who was calling and a fleet of similar helper daemons that deserve the same question.
Why the Exploit Traffic Looks Routine
The exploit traffic is an HTTP POST to a legitimate Splunk endpoint with a Basic auth header. WAF rules tuned for Splunk's known web paths will not flag /en-US/splunkd/__raw/v1/postgres/recovery/backup unless somebody wrote a rule specifically for the recovery proxy. The sidecar is supposed to spawn pg_dump and pg_restore, so EDR baselines treat those parent/child relationships as routine. And the final stage just overwrites an existing script with new bytes, so the only host artifact for hours might be an mtime change on a file your team never inventoried.
The Indicators Worth Alerting On
The Picus Security writeup calls out the most reliable web-log indicators: POSTs to any URL containing /__raw/v1/postgres/recovery/, Basic auth headers with empty or malformed usernames, path-traversal sequences in the URL or body, and PostgreSQL connection-string parameters such as hostaddr=, port=, passfile=, dbname=, and target_session_attrs= turning up where they do not belong.
On the host, EDR should flag pg_restore or pg_dump invoked with a junk -U value or a connection string pointing at a remote host the Splunk instance has no reason to reach. Postgres should never write outside its own data directory, so the high-value EDR signals are:
- File writes by the postgres process into script paths under
$SPLUNK_HOME, or into any directory containing executables that Splunk runs on a schedule. - New files dropped under
/tmpon a Splunk host that are then executed minutes later by a Splunk or postgres process. - Any child of
splunkdorpostgresthat is not on the known-good binary list, especially shells,curl,wget, or interpreters likepythonorperl.
MITRE ATT&CK mapping points the queries at the right log sources. The initial unauthenticated POST is T1190 (Exploit Public-Facing Application). The sidecar abused along the way acts as a Server Software Component, T1505.003, and the lo_export stage co-opts a legitimate PostgreSQL feature into T1059 (Command and Scripting Interpreter) once execution begins. Anything pulled from the Splunk database afterwards, including stored credentials and admin tokens, sits under T1003 (OS Credential Dumping) and T1552 (Unsecured Credentials). And because anyone who owns your SIEM is usually after the telemetry, T1565.001 (Stored Data Manipulation) deserves its own hunt: are there gaps in indexed events that line up with the window the box was reachable?
Patch, Then Hunt Backward
Patch to Splunk Enterprise 10.4.0, 10.2.4, 10.0.7, 9.4.12, or 9.3.13, per Splunk's advisory SVD-2026-0603. If patching has to wait, firewall the sidecar so only trusted Splunk infrastructure can reach it on port 5435 and on any __raw path through splunkd that forwards to /v1/postgres/recovery/. Splunk Enterprise on AWS is the priority population because the sidecar is enabled by default there, per Orca Security. Federal civilian agencies were on a June 21 CISA KEV deadline, which is to say the rest of us are already behind that schedule.
Treat any unpatched, internet-reachable Splunk Enterprise box as already compromised until you can prove otherwise. The patch closes the missing-auth check, but does nothing to undo what an attacker did before it landed: rotate admin and service credentials, regenerate API tokens, replay hunt content back to early June, and verify recent script modifications under $SPLUNK_HOME by hand. If the SIEM your team relies on was the soft entry point, every downstream alert pipeline stays suspect until you can show, with artifacts, that the host stayed clean.
Automate the loop before the next sidecar bug lands.
This is the loop BlueTeamAutomation automates end to end, from BAS coverage of unauthenticated web exploits and abusable management endpoints, through EDR and SIEM correlation on the file-write and process-spawn artifacts, to SOAR-driven isolation and credential rotation when the indicators line up. The detection holds together, the proof that it held lands in audit evidence, and your team does not have to scramble a weekend patch sprint every time a sidecar daemon turns out to have forgotten what authentication is for.
Explore BASzy →