Skip to content
CVE-2026-72899: Metabase Unauthenticated SQL Injection 1dayexploit / 15h The vulnerability affects versions 0.58.0 through 0.63.4 and is caused by insufficient validation of parameter values in the public sharing endpoint. An attacker needs only the public link UUID (which is part of the shared URL by design) to execute arbitrary queries against the Metabase application database as a superuser.

CVE-2026-72899: Metabase Unauthenticated SQL Injection 1dayexploit / 15h The vulnerability affects versions 0.58.0 through 0.63.4 and is caused by insufficient validation of parameter values in the public sharing endpoint. An attacker needs only the public link UUID (which is part of the shared URL by design) to execute arbitrary queries against the Metabase application database as a superuser.

1dayexploit.com • August 11, 2026

CVE-2026-72899 is a critical unauthenticated SQL injection in Metabase that allows an attacker to execute arbitrary SQL queries through a publicly shared dashboard or saved question. The vulnerability affects versions 0.58.0 through 0.63.4 and is caused by insufficient validation of parameter values in the public sharing endpoint. An attacker needs only the public link UUID (which is part of the shared URL by design) to execute arbitrary queries against the Metabase application database as a superuser. CVSS score: 10.0 CRITICAL (NVD vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H ).

Metabase's public query endpoint accepts a parameters list from the URL query string. The schema that defines a parameter value has no constraint at all :

The :any keyword means a JSON object in the request becomes a Clojure map and travels unchanged into SQL compilation. This is the root of the injection.

In metabase.driver.sql.query_processor , a Clojure map is treated as an Object and passed through to Honey SQL untouched:

Honey SQL 2's format function interprets maps as DSL (domain-specific language), not data. A map operand like {"raw": " "} is rendered as verbatim SQL with no quoting and no bound parameter.

The vulnerability is reached through the field-filter path in metabase.driver.sql.parameters.substitution . When a parameter's type is an operator type (e.g. string/= ) and its value is [{"raw": "..."}] , the value is spliced into an MBQL filter clause:

This produces [:= {} {:raw "..."}] , and the attacker's map becomes an operand passed to Honey SQL's formatter.

The update-filter-for-field-type function only rewrites string and sequence-of-string values:

A one-element list containing a map matches neither branch, so the value passes through untouched.

The fix is entirely in metabase.lib.schema.parameter . A new normalize-parameter-value function is added that scalarizes any collection-valued parameter to nil before compilation:

The :decode/normalize hook runs during query normalization in production builds (unlike mu/defn validation), so every parameter value is scalarized before reaching the compiler. Any map or nested collection becomes nil , and a list of values has each element scalarized. Once the value is nil or a scalar, the ["sql" Object] passthrough only ever sees strings, numbers, booleans and nil , which Honey SQL binds as parameters.

All of the following must be true:

The default payload leaks the core_user table with email addresses and bcrypt password hashes - data the shared card's own query can never return, making injection unambiguous.

This injection is a single-step exploit with no race conditions or timing dependencies. Once the field-filter parameter is identified, the vulnerability is reliably exploitable in one request.

The injected SQL lands in a context compiled as WHERE ( = ( )) . A scalar subquery like (SELECT version()) needs no paren balancing. For multi-row results, a derived-table UNION works:

The exploit adapts the column count and text-column position to match the vulnerable card's schema, so it works against any vulnerable field-filter card.

Extracted Entities

Attack Types (1)

Companies (1)

CWE Weaknesses (1)