Skip to content

Research

Inyección SQL sin autenticar en Metabase

All projects

ActiveDockerPostgreSQLBurp SuiteAnálisis de parches

Metabase published a maximum-severity advisory without explaining the vector, giving only a log signature to search for. Two well-known companies had already confirmed attacks through the same flaw. I built a lab with three containers, two vulnerable versions and one patched, and reconstructed the mechanism by sending identical requests to both: the vulnerable one ran a query the patched one did not, with a value I had not supplied anywhere.

Why the code is not here

The lab and the proof of concept are not published. The flaw is patched, but thousands of exposed instances remain unpatched, so this describes the mechanism and not how to exploit it.

The chain behind the flaw

The three together give database access without a single credential.

Responsible useGHSA-vwf4-m7j8-wcjf

This analysis covers a vulnerability already disclosed and fixed by its vendor, and it describes the mechanism of the flaw without handing over anything executable. There is no proof of concept, no reproducible steps and no lab material. If you run an affected system, the link to the official advisory leads to the version that fixes it.

Aviso oficial de Metabase

The starting point

Metabase published a maximum-severity advisory without explaining how to exploit it. Just two sentences and a log signature. Framework and Tally, two well-known companies, had already confirmed attacks targeting that vulnerability. No public proof of concept existed at the time.

If you run that, you know you are exposed and all you have is a signature to search for. I spent a weekend reconstructing the mechanism from what was public.

The lab

Three containers. Two ran versions from the affected range and one ran the patched release, each configured to log every database query it received. The concept was straightforward: send identical requests to all three and analyse differences across the logs.

Two vulnerable versions, deliberately chosen over one. If unexpected behaviour appears across two different vulnerable releases, it is the exploit. If it only appears in one, it might be a quirk of that specific build, wasting half a day chasing ghosts.

The day one mistake

I wasted the entire first afternoon. I misread the affected version range and built the lab with a patched version. Requests that should have failed succeeded, while log outputs came back identical. I spent hours convinced the advisory was exaggerated, or that the vector required something I lacked.

Once I downgraded to the right version, the flaw surfaced on the first try. The vulnerable instance executed a database query absent from the patched version, containing a value I had never supplied anywhere in the request. From there the work stopped being guesswork.

The mechanism

Three chained components, none of which is a severe flaw on its own.

The first sits in the application: an unauthenticated endpoint accepts extra keys in the request payload and passes them internally without sanitisation. The second lies within a query-building library that honours its own escape sequences even when the triggering value originates externally. The third is a database engine default allowing multiple statements in a single query packet.

Aligned together, a single unauthenticated request results in full administrator takeover. This explains the maximum severity score, and why the advisory omitted specifics: each piece looks harmless in isolation, yet the complete chain is trivial to reproduce once seen.

What I will not publish is the request payload, the chain leading to code execution, or the lab configuration. The vulnerability has been patched for weeks, but Shodan still reports over five thousand exposed instances, and not all of them are up to date.

The method

Metabase had removed the source code for recent releases, making direct before-and-after diffing impossible. I downloaded four versions and decompiled them.

I divided up that workload. I mapped where the flaw might reside, then orchestrated several language models in parallel on a fifteen-euro budget. Two models decompiled and analysed version diffs. Two others generated queries against the database. I reviewed logs and eliminated hypotheses. The models did not discover the flaw. Instead, they let me examine four locations at once rather than one.

The resources it took

This was done by somebody with baseline knowledge, from home, in two days and on fifteen euros. I am not a researcher and I have not spent years analysing binaries.

If it works with those resources, the question left is what somebody with time, money and a motive is doing. And I could not tell you whether the method works twice or this one came out right by luck.