CVE-2026-72898 Elastic Security · Elastic

Detect Metabase SQL Injection Exploitation (CVE-2026-72898) in Elastic Security

Detects exploitation attempts and successful exploitation of CVE-2026-72898, a SQL injection vulnerability (CWE-89) in Metabase. Attackers inject malicious SQL through crafted parameters in Metabase query/API endpoints, enabling unauthorized data access, credential theft from the application database, and potential remote code execution via database features. This CVE is on the CISA KEV catalog (BOD 26-04), indicating confirmed in-the-wild exploitation. Detection focuses on anomalous SQL syntax in HTTP request parameters to Metabase endpoints, error-based/blind injection patterns, and unusual database query behavior originating from the Metabase service account.

MITRE ATT&CK

Tactic
Initial Access Credential Access Collection

Elastic Detection Query

Elastic Security (Elastic)
eql
network where destination.port in (3000, 443) and
  (url.path : ("/api/dataset*", "/api/card*", "/api/database*", "/api/public*", "/api/embed*")) and
  (url.query : ("*union*select*", "*or*1=1*", "*pg_sleep*", "*waitfor*delay*", "*information_schema*", "*benchmark(*", "*xp_cmdshell*", "*load_file(*"))
high severity medium confidence

EQL rule matching Metabase API network events whose URL query contains SQL injection tokens.

Data Sources

Packetbeat Network FlowFilebeat Proxy Logs

Required Tables

packetbeat-*filebeat-*

False Positives & Tuning

  • Analyst-authored native SQL queries containing UNION SELECT or information_schema references
  • Approved security scanners generating injection-like traffic
  • Internal monitoring probes that URL-encode SQL for health checks

Other platforms for CVE-2026-72898


Testing Methodology

Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Union-based SQL injection against Metabase dataset endpoint

    Expected signal: Proxy/WAF log entry with POST to /api/dataset containing 'UNION SELECT' and 'core_user' in the decoded body/query.

  2. Test 2Time-based blind SQL injection (pg_sleep)

    Expected signal: Web access log with GET to /api/public/card containing URL-encoded 'pg_sleep(10)' and elevated response latency (~10s).

  3. Test 3Boolean-based blind SQL injection probe

    Expected signal: HTTP request log to /api/card containing decoded \"' OR '1'='1\" injection string.


Response Playbook

Triage

  1. Confirm the target host is running Metabase and identify its version; cross-reference against GHSA-vwf4-m7j8-wcjf to determine if it is within the affected range.
  2. Decode and review the captured request payloads to classify the injection type (union-based, boolean-blind, time-based blind, or error-based) and assess whether it succeeded (e.g., HTTP 200 with anomalous response size/timing).
  3. Identify the source IP reputation and whether the requests were authenticated (valid Metabase session token) or unauthenticated against public/embed endpoints.
  4. Check Metabase application logs for query errors or unusually large result sets correlated with the request timestamps.

Containment

  1. Isolate or place the Metabase server behind a WAF rule blocking the identified injection signatures, or take it offline if active data exfiltration is confirmed.
  2. Block the source IP(s) at the perimeter firewall and revoke any Metabase session tokens associated with the attacker.
  3. Apply the vendor patch from the Metabase security advisory immediately, prioritizing per CISA BOD 26-04.
  4. Restrict the Metabase application database account privileges to least-privilege (no DDL, no file/OS access) as a compensating control.

Evidence Collection

  1. Preserve full HTTP request/response logs, WAF logs, and Metabase application logs covering the attack window.
  2. Capture the Metabase application database query logs to determine which tables and columns were accessed or dumped.
  3. Snapshot the Metabase server disk and memory if RCE via database is suspected (e.g., PostgreSQL COPY TO PROGRAM, MySQL load_file).
  4. Export the Metabase audit log (/api/util/logs) and session table to identify compromised accounts and stolen credentials.

Escalation Criteria

  • !Escalate to incident response if injection is confirmed successful (data returned, sensitive tables enumerated, or credentials in the Metabase DB accessed).
  • !Escalate to legal/compliance if customer or PII data stored in connected databases was accessed via the injection.
  • !Escalate to CISO/executive if RCE is achieved on the Metabase host or lateral movement into connected data sources is observed.
  • !Notify per CISA KEV/BOD 26-04 reporting obligations if the asset is a federal or regulated system.

Investigation Guide

Related Techniques

Forensic Artifacts

  • >Metabase application logs (query errors, stack traces) at the exploitation timestamps
  • >Web/proxy access logs containing the URL-encoded injection payloads
  • >Metabase metadata database session and audit tables
  • >Application DB query logs showing information_schema enumeration or credential table reads

Tuning Guidance

Baseline the native SQL queries your legitimate Metabase analysts run — many reference information_schema and UNION SELECT normally. Scope the detection to unauthenticated or public/embed endpoint hits first, since those cannot legitimately contain analyst SQL, then layer in time-based/blind signatures (pg_sleep, waitfor, benchmark) which almost never appear in benign traffic. Whitelist known scanner IPs and internal BI automation service accounts. Prioritize alerts where the request came from an external/untrusted network zone.


Hunting Queries

Hunts for time-based blind SQL injection bursts (sleep/delay functions) against Metabase endpoints, which indicate automated blind extraction attempts.

Hunting — KQL
kql
CommonSecurityLog | where RequestURL has_any ("/api/dataset","/api/card","/api/public","/api/embed") | extend d = url_decode(RequestURL) | where d has_any ("pg_sleep","waitfor delay","benchmark(") | summarize count() by SourceIP, bin(TimeGenerated, 1h) | where count_ > 5
Hunting — SPL
spl
index=web (uri_path="/api/dataset*" OR uri_path="/api/public*") | eval d=urldecode(uri_query) | where match(d,"(?i)(pg_sleep|waitfor delay|benchmark\()") | stats count by src_ip, date_hour | where count > 5

Atomic Red Team Tests

Test 1 Union-based SQL injection against Metabase dataset endpoint
linux

Simulates a union-based SQL injection payload sent to the Metabase /api/dataset endpoint in a lab environment.

Command

bash
curl -s -X POST 'http://metabase.lab.local:3000/api/dataset' -H 'Content-Type: application/json' --data '{"database":1,"type":"native","native":{"query":"SELECT * FROM users UNION SELECT username, password FROM core_user -- "}}'

Cleanup

bash
echo 'No persistent artifacts created; clear shell history: history -c'

Expected Telemetry

Proxy/WAF log entry with POST to /api/dataset containing 'UNION SELECT' and 'core_user' in the decoded body/query.

Expected Detection

KQL/SPL rules fire on the union select signature against the Metabase API path.

Test 2 Time-based blind SQL injection (pg_sleep)
linux

Sends a time-based blind injection payload using pg_sleep to a Metabase public embed parameter.

Command

bash
curl -s 'http://metabase.lab.local:3000/api/public/card/abcd-1234?param=1%27%3B%20SELECT%20pg_sleep(10)--'

Cleanup

bash
history -c

Expected Telemetry

Web access log with GET to /api/public/card containing URL-encoded 'pg_sleep(10)' and elevated response latency (~10s).

Expected Detection

Hunting query and network SQLi rules flag pg_sleep time-based blind pattern.

Test 3 Boolean-based blind SQL injection probe
windows

Issues a boolean-based blind injection ('1'='1) against the Metabase card query API to test truthy/falsy response differences.

Command

powershell
powershell -Command "Invoke-WebRequest -UseBasicParsing -Uri 'http://metabase.lab.local:3000/api/card/1/query?filter=1%27%20OR%20%271%27%3D%271' -Method GET"

Cleanup

powershell
powershell -Command "Clear-History"

Expected Telemetry

HTTP request log to /api/card containing decoded \"' OR '1'='1\" injection string.

Expected Detection

SIEM SQLi signature rules match the boolean-based or 1=1 pattern on the Metabase endpoint.

Related Detections