Skip to content

Back to the catalog

Inside the Metabase SQLi: Exploited in the Wild
wiz.iowriteup

Inside the Metabase SQLi: Exploited in the Wild

Wiz Research reverse-engineers CVE-2026-72898 (GHSA-vwf4-m7j8-wcjf), a zero-day SQL injection in Metabase's /api/session/reset_password endpoint exploited in the wild against Metabase Cloud since August 2026. The bug chains Clojure's merge (which lets an attacker-supplied user-id survive an auth-result merge), JSON keywordization, and HoneySQL's :raw keyword to smuggle unparameterized SQL into a t2/select-one query, yielding blind SQL injection. The post walks through decompiling patched vs. vulnerable JARs to reconstruct the flaw, notes ~2,500 internet-exposed Metabase instances per Shodan, and gives a curl-based exploitability check plus remediation guidance.

TL;DR Root-cause writeup of Metabase's in-the-wild-exploited zero-day SQLi (CVE-2026-72898), reconstructed via JAR diffing of Clojure/HoneySQL internals.
Document

What to do

The summary names the curl-based check but not the command. To test exploitability, modify the payload with your own SQL:

curl -X POST https://TARGET/api/session/reset_password \
-H "Content-Type: application/json" \
-d '{"token":"x","password":"y","user-id":{"raw":"SQL_PLACEHOLDER"}}'

To fingerprint the version (and thus whether an instance is vulnerable) without exploiting, review the /api/session/properties endpoint. Self-hosted instances must be patched immediately; the fix ships only in releases, not in the public GitHub repo.

Preconditions / Affected

Vulnerable from version 1.58 onward — introduced when the auth_identity module was refactored. Wiz used v0.58.22 (vulnerable) and v0.58.24 (patched) to build the diff. The injection is blind and its payload is database-dependent: H2 by default, but PostgreSQL/MySQL/MariaDB in production, so a working payload must match the backend.

How the fix works (the smoking gun)

The patch validates user-id as a positive integer before it reaches the query:

(if (pos-int? user-id)
  (t2/select-one [:model/User ...] :id user-id)
  (log/warnf "... refusing to resolve a user." ...))

Because /api/session/reset_password documents only token and password, the presence of a user-id guard confirms the attack shape: an undocumented user-id key that isn't stripped, surviving the (merge request (authenticate ...)) when auth fails, then reaching HoneySQL as {:raw "SQL"}.

Exposure and exploitation status

Beyond the ~2,500 Shodan-inventoried instances the summary cites, Wiz observed that ~13% of cloud environments run self-hosted Metabase, ~25% of those fully internet-accessible. As of noon UTC August 10th, 2026, public proof-of-concept exploits have been open-sourced — so the exploitability window for unpatched instances is now wide, not theoretical. Wiz is withholding its own full PoC.

Note on methodology

The post also describes variant hunting after root-cause: generating static-analysis rules for the relevant patterns, then using an agent to validate candidates. They reviewed all merge.*request patterns and every auth-identity/login! call site — a repeatable approach if you maintain a Clojure/HoneySQL codebase and want to check for the same class of bug.

Organisations named here

  • GHSA-vwf4-m7j8-wcjf
  • Wiz Research

CVEs named here

  • CVE-2026-72898

Technologies named here

  • Metabase
  • Metabase Cloud
  • H2
  • PostgreSQL
  • MySQL
  • MariaDB
  • Shodan
  • Clojure
  • HoneySQL