Blog
MetabaseSQL InjectionZero-DayData Exfiltration

Metabase Zero-Day SQL Injection: When Your BI Tool Owns Every Database

An unauthenticated CVSS 10 SQL injection turned Metabase into a pivot into every connected production database. Framework and Tally lost customer data before anyone noticed.

Zero Hunt Research··10 min read

On 6 August 2026 Metabase published an emergency security notice and shipped patches across six release lines at once. The reason surfaced a day later: an unauthenticated SQL injection, tracked as GHSA-vwf4-m7j8-wcjf and scored CVSS 10.0, had already been used as a zero-day to breach live customer instances and steal data. Two of the victims — the laptop maker Framework and the form builder Tally — disclosed the theft publicly. The interesting part is not the injection itself. It is what Metabase is: a business-intelligence server that, by design, holds live credentials into every database an organisation cares about. An unauthenticated bug in that box is not an application vulnerability. It is a credential to the whole warehouse.

What the Metabase zero-day actually does

The flaw lives in a single unauthenticated endpoint: POST /api/session/reset_password. Metabase's own advisory is blunt about the consequence — an attacker who reaches that endpoint can "inject arbitrary SQL into the Metabase application database, which can give them administrator access to the instance." No login, no token, no prior foothold. One request to a password-reset route, and the attacker is writing SQL against the application's own metadata store.

Administrator access to a Metabase instance is not the ceiling; it is the floor. Once inside, the advisory notes, the attacker can change application configuration, read the stored credentials for every connected database, and export any data reachable through those connections. Metabase encrypts connection secrets at rest, but an admin session decrypts them in the ordinary course of doing its job — that is what the tool is for. The vector is CVSS 10 for the reason CVSS 10 is rare: AV:N/AC:L/PR:N/UI:N with a scope change and total confidentiality, integrity, and availability impact. Network-reachable, trivial, no privileges, no user interaction, and it breaks out of its own security scope into everything it touches.

One detail worth flagging for anyone whose vulnerability programme is CVE-driven: this flaw has no CVE. It is tracked only as a GHSA advisory. Scanners and asset-management pipelines that key exclusively on the CVE feed will not fire on it, and the NVD enrichment that usually assigns a CVSS is absent. If your triage rule is "no CVE, no ticket," a CVSS 10 unauthenticated RCE-equivalent slipped straight through it this week.

Why a BI platform is the worst host for an unauthenticated SQL injection

Most critical web vulnerabilities are bounded by what the compromised application itself stores. A SQL injection in a forum leaks the forum's users. A SQL injection in a BI tool leaks whatever the BI tool can query — and a BI tool is deliberately wired to query everything.

Metabase is an aggregation point. To do its job it holds standing, long-lived service credentials into production Postgres, MySQL, Snowflake, BigQuery, Redshift, and whatever else feeds the dashboards. Those credentials are usually broad — analysts do not want to file a ticket every time they need a new column, so the Metabase service account is frequently granted read across whole schemas, sometimes whole clusters. That is a reasonable trade-off for an internal analytics tool sitting behind authentication. It is a catastrophic one for an internal analytics tool with an unauthenticated SQL injection on its front door.

The blast radius, then, is not the size of the Metabase application database. It is the union of every dataset every Metabase connection can read. And crucially, the attacker does not need to find, crack, or move laterally to those databases. Metabase already did the hard part — it authenticated to them, holds the sessions open, and exposes a query surface over them. The injection just borrows the keys that are already in the ignition.

"We patched within hours of the advisory. Are we safe?"

"You're safe from the next attacker. The one who came through on the 3rd already read your connection secrets and exported the tables. The patch closes the door. It does not un-send the data, and it does not rotate the database passwords the attacker now has."

That exchange is the entire lesson of this incident. Patching an actively-exploited zero-day is necessary and does nothing for the window that already elapsed.

Framework, Tally, and the shape of the breach

The public victims give the abstract risk a concrete shape. According to BleepingComputer's reporting and coverage in The Hacker News, the attacks hit Framework and Tally on 3 August, three days before the patch existed. Framework reported the theft of customer names, email addresses, login IP addresses, billing and shipping addresses, phone numbers, and company names. Tally reported stolen email addresses and password hashes — one-way cryptographic hashes rather than plaintext — while its form-submission data was untouched. LexisNexis was named as impacted through a third-party vendor, with the exposure scope still unclear at disclosure.

Two things stand out. First, the data classes match the "everything the BI tool can read" model exactly — this is not one leaked table, it is customer records assembled across whatever the dashboards join together. Second, and more important: the victims did not detect the intrusion. Metabase notified them. Framework learned of its exposure on 6 August, when the vendor disclosed the flaw — not on 3 August, when its own data walked out the door. That three-day gap between compromise and awareness is not a Framework failing. It is the default outcome for exfiltration that travels over connections the environment is built to trust.

The detection gap: exfiltration over connections that are supposed to be there

Here is why this class of breach is so consistently missed. Every control on the perimeter is watching for the wrong thing.

An endpoint agent on the Metabase host sees a legitimate process — the Metabase JVM — opening database connections it opens all day, every day. A SIEM correlation rule looking for failed logins or new admin accounts sees nothing unusual, because the attacker used an unauthenticated endpoint and inherited the application's own identity. A signature-based network monitor sees TLS to the same database hosts and the same upstream that Metabase always talks to. Nothing tripped a rule because, at the level those tools reason about, nothing was anomalous. The bytes were wrong; the metadata was fine.

What was anomalous was the shape of the traffic. A BI server's normal profile is heavy ingest from databases and light egress to browsers rendering dashboards. During this attack the profile inverts: sustained, high-volume outbound from a host that historically only pulls in, often to a destination — an attacker-controlled endpoint or a never-before-seen ASN — that the host has no business talking to. That inversion is visible on the wire in real time, while the export is running, regardless of which process opened the socket or whether the CVE feed has caught up. It is exactly the signal that log-and-identity tooling structurally cannot see and that behavioural traffic analysis is built to catch.

Remediation

Metabase's advisory and the incident reporting give enough to build a complete runbook. Treat any exposed, unpatched instance as compromised until proven otherwise — this was exploited as a zero-day, so "we patched fast" does not mean "we were never hit."

1. Am I affected? Check your running version against the affected ranges. The flaw affects Metabase 1.58 and above up to the fixes; concretely, the vulnerable builds are:

Release line Affected Fixed in
58 58.0 – 58.23 0.58.24 / 1.58.24
59 59.0 – 59.20 0.59.21 / 1.59.21
60 60.0 – 60.16 0.60.17 / 1.60.17
61 61.0 – 61.10 0.61.11 / 1.61.11
62 62.0 – 62.8 0.62.9 / 1.62.9
63 63.0 – 63.3 0.63.5 / 1.63.5

Metabase Cloud instances were patched by the vendor. Only self-hosted deployments need action. Confirm your build from the Admin → Troubleshooting page or GET /api/session/properties (the version field), not from your last-remembered deploy.

2. Patch. Upgrade to the fixed release for your line, verbatim from the table above. Do not "upgrade to latest" blindly across major lines without checking your own breaking-change notes — pick the patched build on your current line so the fix is the only change.

3. Can't patch this minute? Contain the endpoint. Block POST /api/session/reset_password at your reverse proxy or WAF until the upgrade lands. In nginx: location = /api/session/reset_password { return 403; }. This disables the self-service password-reset flow, which is an acceptable trade for a few hours. It is a stopgap, not a fix — SQL injection primitives frequently have more than one reachable sink, so treat the block as buying time to patch, not as a substitute.

4. Hunt for compromise. Metabase published a precise indicator: a POST /api/session/reset_password returning HTTP 400, followed by a GET /api/user/current returning HTTP 200 from the same source, is the exploitation signature. Grep your reverse-proxy and application access logs for that pairing. Beyond the signature, hunt for the consequences: unexpected changes to database connection settings, new or modified admin users, large or unusual data exports, and outbound connections from the Metabase host to destinations outside its normal set. Map the chain to MITRE ATT&CK for your detection and reporting:

  • T1190 — Exploit Public-Facing Application (the unauthenticated injection)
  • T1078 — Valid Accounts (admin access on the instance)
  • T1552.001 / T1555 — Credentials from stored connection secrets
  • T1213 — Data from Information Repositories (the connected databases)
  • T1041 / T1567.002 — Exfiltration over the attacker's channel / web service

5. Eradicate and verify. Patching does not revoke what the SQL injection already read. Because the attacker's real prize was the downstream credentials, eradication has to reach past Metabase:

  • Revoke all active Metabase sessions and rotate the application's own secret/encryption key.
  • Rotate the credentials for every database Metabase connects to. These are the keys the attacker exported; the patch does not change them. This is the step most incident write-ups skip and the one that actually closes the breach.
  • Audit admin accounts and API keys created or modified since your earliest possible exposure, and remove any you cannot account for.
  • Rotate any secrets that were themselves stored in the reachable databases (application API keys, third-party tokens), because those left too.
  • Verify by state, not by changelog: confirm the running version is a fixed build, confirm the reset-password endpoint no longer yields the 400-then-200 pattern, and confirm the rotated database credentials are the only ones now accepted.

Where Zero Hunt fits

The three days between Framework being breached and Framework being told is the problem worth solving, and it is a network problem before it is a log problem. Every host-based and identity-based control in that environment was reasoning about the wrong layer — a trusted process using trusted connections — while customer data left over exactly those connections.

This is the case Zero Hunt's AI Traffic Analysis pillar was built for. It is a proprietary deep-learning model, trained on billions of PCAP sequences, running locally on the appliance GPU at a 2.7+ Gbit/s baseline — no cloud, no callbacks. Its four inference heads (suspicious traffic, malware classification, attack-type identification, application fingerprinting) reason about the shape of a session, not its signature. A BI server whose historical profile is ingest-heavy suddenly sustaining high-volume egress to a never-seen ASN is precisely the anomaly the suspicious-traffic head is trained to surface — while the export is happening, not in the next morning's SIEM digest, and independent of whether the exploited flaw ever gets a CVE. When the exfiltration rides connections your endpoint and identity tooling are built to trust, the wire is the only place the truth is still visible.

The upstream half is validation. A Metabase server holding broad read into production is exactly the kind of over-permissioned aggregation point that a continuous offensive test should flag before an attacker finds it — an internet-reachable admin surface with credentials into everything behind it. Zero Hunt's 10-agent generative pentest engine writes a fresh exploit chain per target, backtested in the AI Gym before it runs in production and ECDSA-signed per finding, so the "our BI tool can read the entire warehouse and it is one unauthenticated bug away from the internet" risk shows up in a report you can act on — not in a breach notification from your vendor.

Patching GHSA-vwf4-m7j8-wcjf was the easy part, and most teams did it within a day. The hard part — knowing whether the three days before the patch cost you anything — is a question only the network can answer, and only if something was watching it.