Back to Blog

Metabase: the data dashboard that was also the keyring

It does not hold your data. It holds the keys to your data.
Metabase · GHSA-vwf4-m7j8-wcjf · CVSS 10.0

On 3 August somebody walked into Metabase instances hosted by the vendor itself and took customer data. No phishing, no leaked password, no careless administrator. There was a POST request to /api/session/reset_password — the "I forgot my password" endpoint, the one that by definition has to answer without a session — and it accepted SQL. The advisory went out on 6 August with a CVSS of 10.0, the top of the scale. Framework and Tally have already notified their users. And the detail that makes this bigger than an urgent patch: what an attacker takes from a compromised Metabase is not the charts.

What is actually inside a BI dashboard

Metabase is a viewer. It is not where your data lives: it is what queries it. In order to query it, it stores, inside its own application database, the connection details for every database you have plugged into it: host, port, username and password. And the injection in this advisory goes precisely against that application database. Not against the data warehouse: against the notebook where the warehouse keys are written down.

The vendor advisory lists it without decoration: an attacker on a compromised instance can change the application configuration, steal the stored credentials for connected databases, read any data reachable through those connections and export it. Read that again with your own installation in mind, and count how many databases your Metabase has connected. That number is not "how many sources do I have". It is how many systems get compromised at once.

There is one more layer, and it is the one plenty of people are discovering this week: those credentials are not encrypted by default. Metabase's documentation presents encryption of connection details as something you enable, by creating a key and setting it in the MB_ENCRYPTION_SECRET_KEY environment variable. If nobody set it on deployment day — and on a deployment done in a hurry nobody does — there they are, in the clear.

Now the caveat, which matters to us more than the headline: setting it would not have saved you, but it would have saved you half. The injection targets the application database, not the process environment: if the details are encrypted, what comes out of that table is a useless AES blob without the key, and that does take away the cleartext password the attacker walks off with for later. What it does not prevent is that, once inside as an administrator, they ask Metabase itself to run the query: the dashboard decrypts, connects and shows them the data anyway. Encryption does not close the window on this incident, but it sharply reduces what the attacker keeps once the window shuts — which is precisely the expensive part, as you will see below. Set it if you have not.

The service account nobody has looked at since

The connection gets created on day one, when the priority is getting the chart out. Whatever user was at hand gets used, or a new one is created with broad permissions "so all the tables show up and we do not have to touch this again". Nobody touches it again, indeed. Two years later that user still has read access across the whole schema, and its password has now been sitting somewhere reachable without authentication.

And there is a multiplier that rarely gets mentioned: a Metabase administrator can write native SQL against the connections. Which means the attacker who promotes themselves to admin does not need to know your data model, guess table names or bring tooling. They ask the dashboard, which is what it is for, and the dashboard shows them, neatly, with an export button. If your connection uses a read-only user scoped to a specific schema, the damage is scoped with it. That is not advanced hardening: it is how the connection should have been created on day one.

A hole your patch inventory cannot see

The flaw was published as a GitHub security advisory, GHSA-vwf4-m7j8-wcjf, and at the time of writing it has no CVE assigned. It is worth pausing here, because the operational consequence is concrete: if your vulnerability management process consists of receiving a CVE bulletin and cross-referencing it against a product list, this 10.0-scored, actively exploited hole does not show up. There is nothing to cross-reference. As far as your process is concerned, it does not exist.

This is not a quirk of this case. Projects hosted on GitHub publish their advisories there, and the CVE is a separate process that sometimes arrives late and sometimes not at all: this one, at 10.0 and with confirmed exploitation, still had none when we wrote this. The practical difference is what you watch: whoever watches versions — an inventory of what is installed, compared periodically against the vendor's release notes — finds out the same day. Whoever watches CVEs finds out when somebody tells them.

Look closely at the number before deciding you are fine

The affected ranges in the advisory are 58.0 to 58.22, 59.0 to 59.19, 60.0 to 60.15, 61.0 to 61.9, 62.0 to 62.7 and 63.0 to 63.2. The fixed versions are 58.24, 59.21, 60.17, 61.11, 62.9 and 63.5. And a warning about those two lists: they do not meet. The advisory flags everything below 63.3 as affected, but fixes in 63.5; it flags everything below 62.8, and fixes in 62.9. If your number falls in that gap — a 62.8, a 63.3, a 63.4 — the advisory literally says nothing about you. We would go to the fixed version rather than the edge of the range: it is the only one of the two lists the vendor actually says contains the fix.

There is a reading trap here that will make somebody file the advisory away by mistake. A lot of the coverage says "affects 1.58 and above", you look at your container, read v0.62.4 and relax. Do not relax. Metabase prefixes a 0 or a 1 depending on the edition: 0 is the open-source build, 1 is the commercial one for the Pro and Enterprise plans, with the same version number behind it. A v0.62.4 and a v1.62.4 are the same version number in two editions: the commercial one ships extra features, but for reading this advisory's range they count the same. So "1.58 and above" and "branches 0.58 through 0.63" come to exactly the same thing.

Versions before 58 are not in range. With one caveat we make without smiling: if your comfort today is that you have not upgraded in two years, your problem is not smaller, it is a different one. And if you cannot upgrade in the next few hours, the advisory itself gives the stopgap that works: block the endpoint /api/session/reset_password at whatever proxy or load balancer sits in front. It breaks "forgot my password" and it breaks nothing else.

And there is a check you can run right now, with no tooling: the published indicator is a POST to /api/session/reset_password returning 400, followed, from the same IP and within seconds, by a GET to /api/user/current returning 200. In other words: the request "fails", and immediately afterwards that same IP is authenticated. Without correlating by source and time the pattern is worthless, because a 200 on /api/user/current is what any browser with an open session produces. If you keep proxy logs, it is a two-minute search. If you do not keep them, you have just found the first task on the list.

Upgrading is the easy half

The post-patch list in the advisory — which the vendor conditions on your endpoint having been reachable from the internet — has six items: delete every row in the core_session table in the application database, review your API keys and delete any you do not recognise, check for changes to administrator accounts, rotate the credentials for connected databases, review data warehouse access logs, and review Metabase's own activity and query history. Five of those six can be done in an afternoon.

The fourth one cannot, and it is the one that decides whether the incident actually closes. Rotating the connection password means touching the production database, coordinating a window, warning everyone who depends on those reports and risking breaking the dashboard management looks at on Mondays. It looks nothing like upgrading a container: hours of coordination instead of minutes of deployment, so it gets written down as "next week". And next week the Metabase is clean, patched, administrators reviewed… and the attacker still holds a valid credential against your production database, which is what they took. It is the same pattern we described with the CI/CD server that holds the keys to production: patching the system does not rotate what the system was holding.

Whose dashboard is it?

A Metabase is almost never installed by the IT department. The data team, the product team or marketing stands it up, because they needed a chart on Thursday and it was one docker run. It is a good tool and that ease is a virtue, not a reproach. The problem is what comes with it: it is born outside the inventory, outside the update window, outside the list of things that get patched, and with a port published "temporarily" so the salesperson on the road can see it.

There is a measurement of this, and it is not from this week. In March 2026, research by OX Security counted more than 17,000 Metabase instances exposed on the internet according to Shodan, many of them running versions vulnerable to a remote code execution flaw from 2023. The report does not quantify how many of those 17,000 remained unpatched, and we are not going to inflate the figure: what it does say is that three years after the patch shipped, the flaw is still found on the internet by the thousand. That is the floor a 10.0-scored advisory lands on.

The operational question is the usual one, the same we asked about who maintains your WordPress: if a critical advisory for your BI tool comes out this morning, who gets the email? If the answer is "whoever installed it, if they still work here", the problem is not Metabase's. And if the answer is "I am not sure we have one", that is today's finding.

The endpoint is public by design; the internet does not have to be

It is worth noticing where the hole was, because it is not a coincidence. The password recovery endpoint is, by definition, the one that has to answer people who cannot authenticate. It sits at the door, in front of access control, in every application in the world. The interesting question is not whether that endpoint should exist — it must — but who should be able to call it.

A BI dashboard is an internal tool. Behind a VPN, or behind identity-based access like the one we build in Zero Trust projects, this same flaw goes from "anyone with an internet connection is an administrator of your dashboard" to "somebody already inside could be". It does not remove it, and we are not going to pretend otherwise. It shrinks the pool of possible attackers from several billion to your payroll, and turns an hours-long race against bots into an incident you investigate with names. Against the usual objection — "but people check it from home" — that is a legitimate need with three or four solutions, and none of them is publishing the login page on the internet.

And then there is the part you do not decide

Framework and Tally are not in this story because they were careless. Framework has said that Metabase notified them on 6 August that their instance had been accessed on the 3rd, and what left were customer names, emails, addresses and phone numbers. Tally mentions email addresses and password hashes. Neither company had an unpatched server: they had a supplier.

That is the uncomfortable part of this class of incident, and the part vendor questionnaires cover worst. When you ask a third party "which tools process our data?", the answer almost never includes the internal dashboard their team uses to look at your account's metrics. Not out of bad faith: because to them that dashboard is not a system processing customer data, it is the screen where they check how the month is going. It is worth adding the question to the questionnaire, and worth being able to answer it yourself when somebody asks you.

The order we would do it in

  • Find the dashboards. Not the ones in the inventory: the ones that exist. A docker ps across the data team's servers and a pass over internal DNS records usually turns up more than one surprise.
  • Compare your version against the range, ignoring the leading 0 or 1. Upgrade to 58.24, 59.21, 60.17, 61.11, 62.9 or 63.5 depending on your branch.
  • Search for the 400-then-200 pattern from the same IP in proxy logs, from early August backwards. And review the administrator list name by name: promotion to admin is the goal of the attack, and one account too many is the evidence.
  • Rotate the credentials for every connected database. All of them. It is the expensive task, the one that gets postponed, and the only one that takes back from the attacker what they took. While you are there, swap them for scoped read-only users, the conversation that has been pending since day one.
  • Look at yourself from outside. Does your dashboard answer from an internet IP? If it does, put a door in front of it before the week is out.
  • And the permanent one: give the dashboard a named owner, put it in the inventory and make sure somebody receives the vendor's release notes. Without that, you will hear about the next advisory from the press too.

When this hurts less (and when it only looks like it)

If you use Metabase Cloud, the patch is not your job: the vendor blocked the attack endpoints and upgraded hosted instances without you doing anything. But the patch not being yours does not take you off the list — rather the opposite: the two compromised instances we know by name, Framework and Tally, were hosted instances. Review the administrator list, clear sessions and rotate the credentials for connected databases exactly as if the server were yours. The patch closes the door; it does not undo what happened before it closed. If you are below version 58 you are not in this range, though, as we said above, that puts you in a worse one. And if your dashboard has never been reachable outside a management network and the connection uses a scoped read-only user, upgrade calmly and rotate when you can: your real exposure is small, and saying so is more useful than scaring you.

What does not work as reassurance is "there is only sales data in there". Sales data means your customers' names, emails, phone numbers and addresses, and leaving through a dashboard's door does not turn it into something else. It is exactly what Framework has had to tell its own customers this week.

We do not sell Metabase or any BI tool, and this is not an argument against it: it is a good piece of software with a serious flaw and a fast vendor response. The work we do is the work around it — knowing which internal applications exist, who maintains them, what credentials they hold and who we let reach them — as part of everyday cybersecurity and data and applications work. If you do not know how many dashboards are plugged into your databases, or which user they connect with, get in touch and we will look at it with you.

A note on sources. The identifier GHSA-vwf4-m7j8-wcjf, the CVSS 10.0 score, the /api/session/reset_password endpoint, the affected and fixed version ranges, the post-patch action list and the stopgap of blocking the endpoint, from the security advisory published by Metabase on 6 August 2026, which at the time of writing has no CVE assigned. The 3 August access to hosted instances, the notification to Framework on the 6th, the data affected at Framework and Tally, the indicator of a POST returning 400 followed by GET /api/user/current returning 200, and the vendor's wording on what an attacker can do on a compromised instance, from coverage by BleepingComputer and SecurityOnline. That encryption of connection details is enabled by creating the MB_ENCRYPTION_SECRET_KEY variable and is not on out of the box, from Metabase's documentation. The 0 prefix for the open-source edition and 1 for the commercial one, with the same version number behind, from the project's own versioning guide. The 17,000-plus instances exposed on Shodan and the persistence of a 2023 flaw, from the OX Security study published in March 2026; that report does not break down how many of those instances remained unpatched. The reading on credential aggregation, tool ownership and the order of response tasks is our own. Cover image: "Real-time bus tracking control room in Lebanon" via Wikimedia Commons, under a CC0 public domain dedication.

Share:

Subscribe to our newsletter

To receive IT stories, everyWAN news and exclusive subscriber offers, sign up to our mailing list

Minorisa de Sistemas Informaticos y Gestión S.L. © 2026
everyWAN
everyWAN