Two technology companies — laptop manufacturer Framework and workflow platform Tally — have publicly disclosed data-theft breaches after attackers exploited a SQL injection vulnerability in unpatched instances of Metabase, the popular open-source business intelligence and analytics platform. The intrusions resulted in unauthorized access to customer data stored in backend databases that the compromised Metabase instances were connected to.
This is the pattern defenders dread most: a third-party analytics tool, deployed with broad read access to production databases, compromised via a classic injection flaw — and turned into a direct tunnel into the crown jewels. Metabase doesn't just query your data; by design it holds credentials to every database it connects to. When an attacker gains SQL injection against a Metabase deployment, they are rarely limited to what the vulnerable query intended to return — they inherit whatever the Metabase service account can see.
If you run Metabase in any capacity — self-hosted JAR, Docker container, or embedded deployment — treat this as an active-threat event. Verify your version, hunt for exploitation, and audit database account scope today.
Technical Analysis
What Happened
According to the disclosures covered by BleepingComputer, threat actors identified and exploited Metabase instances that had not been patched against a known SQL injection flaw, using the vulnerability as the initial access vector to breach both Framework and Tally. The attackers' objective was data theft: once inside the Metabase application context, they leveraged the platform's native ability to execute queries against connected databases to enumerate and exfiltrate customer information.
This campaign underscores three uncomfortable truths about BI/analytics platforms in enterprise environments:
- They are privileged by design. Metabase connects to data warehouses and production databases using service credentials, often with read access to entire schemas — including customer PII, order records, and support data.
- They are frequently under-patched. Analytics tools are often deployed by data or product teams outside the standard vulnerability management pipeline, running months or years behind on updates.
- They are internet-reachable more often than they should be. Metabase is commonly exposed for dashboard sharing, embedding, or remote access — making it directly scannable and exploitable from the public internet.
Affected Products and Attack Surface
- Product: Metabase (open-source and enterprise editions), self-hosted deployments
- Deployment models at risk: Standalone
metabase.jarrunning under a JVM, Docker containers (metabase/metabase), and embedded/white-labeled deployments - Attack vector: Unauthenticated or low-authentication SQL injection through Metabase's query handling / API endpoints, exploited against instances running outdated versions
- Impact: Arbitrary SQL execution within the context of the Metabase database connection — enabling reads against any table the Metabase service account can access, and in some configurations, access to the Metabase application database itself (which stores connection credentials for all configured data sources)
Why SQLi in Metabase Is Worse Than SQLi Elsewhere
A traditional SQL injection is bounded by a single application's data model. Metabase is a universal database client. A successful injection can mean:
- Direct extraction of any table in any connected database (customers, payments, credentials, internal analytics)
- Reading the Metabase application database, which stores encrypted connection strings for all configured data sources — and where the encryption key (
MB_ENCRYPTION_SECRET_KEY) is at a default or recoverable value, full credential recovery for downstream databases - Pivoting to stacked-query execution or database-native features (e.g., PostgreSQL
COPY ... TO PROGRAMwhere permitted) for command execution, depending on the driver and permissions in play - Quiet, low-and-slow exfiltration that looks indistinguishable from legitimate dashboard queries in volumetric terms
Exploitation Status
- Confirmed active exploitation in the wild — Framework and Tally are named victims, and both incidents involved customer data theft
- Opportunistic scanning for internet-exposed Metabase instances should be assumed; Shodan/Censys indexing makes vulnerable versions trivially discoverable
- No public indication of CISA KEV listing at time of writing, but the confirmed-victim threshold for urgency has already been crossed — do not wait for a KEV entry to act
Detection & Response
The most reliable detection surface for this threat is the Metabase application logs and the web/WAF/proxy logs in front of it, followed by the process behavior of the JVM hosting Metabase and query telemetry from the connected databases themselves. The rules and queries below are tuned to be high-fidelity; deploy them against your reverse proxy, WAF, and endpoint telemetry.
Sigma Rules
---
title: SQL Injection Patterns in HTTP Requests Targeting Metabase API
id: 3f8c2a91-7b4e-4d6a-9f12-8e5b1c4a7d90
status: experimental
description: Detects common SQL injection payloads in HTTP requests directed at Metabase API and query endpoints, consistent with exploitation activity seen in the Framework and Tally data-theft breaches.
references:
- https://www.bleepingcomputer.com/news/security/framework-tally-disclose-metabase-data-theft-attacks/
- https://attack.mitre.org/techniques/T1190/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.initial_access
- attack.t1190
logsource:
category: webserver
detection:
selection_endpoint:
c-uri|contains:
- '/api/dataset'
- '/api/card'
- '/api/native'
- '/api/database'
- '/api/query'
selection_sqli:
c-uri|contains:
- '%27%20OR%20'
- '%27%20UNION%20'
- 'UNION%20SELECT'
- 'UNION+SELECT'
- '%3B%20SELECT%20'
- 'information_schema'
- 'pg_catalog'
- 'pg_sleep'
- 'SLEEP%28'
- 'WAITFOR%20DELAY'
- 'COPY%20'
condition: selection_endpoint and selection_sqli
falsepositives:
- Authenticated security scanning tools (verify source IP against approved scanner ranges)
level: high
---
title: Metabase JVM Process Spawning Unexpected Child Processes
id: 9d1e4b72-5c38-4f8a-b2e6-7a0c3d9f1e84
status: experimental
description: Detects the Java process hosting Metabase spawning shells or system utilities, which may indicate post-exploitation activity following SQL injection (e.g., via database-native command execution features).
references:
- https://www.bleepingcomputer.com/news/security/framework-tally-disclose-metabase-data-theft-attacks/
- https://attack.mitre.org/techniques/T1059/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.execution
- attack.t1059
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentCommandLine|contains:
- 'metabase.jar'
- 'metabase'
selection_parent_java:
ParentImage|endswith:
- '/java'
selection_child:
Image|endswith:
- '/sh'
- '/bash'
- '/dash'
- '/curl'
- '/wget'
- '/nc'
- '/ncat'
- '/python'
- '/python3'
- '/base64'
- '/id'
- '/whoami'
condition: (selection_parent or selection_parent_java) and selection_child
falsepositives:
- Container health-check scripts in orchestrated environments (tune by parent process path)
level: critical
---
title: Anomalous Outbound Network Connections from Metabase Server Process
id: 6b2f8c14-3a97-4e5d-8c41-2f9e6b0a5d73
status: experimental
description: Detects the Metabase Java process initiating outbound connections to non-database destinations, a potential indicator of data exfiltration or C2 following exploitation. Baseline expected destinations (connected databases, Metabase license/telemetry endpoints) before deployment.
references:
- https://www.bleepingcomputer.com/news/security/framework-tally-disclose-metabase-data-theft-attacks/
- https://attack.mitre.org/techniques/T1041/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.exfiltration
- attack.t1041
logsource:
category: network_connection
product: linux
detection:
selection_process:
Image|endswith: '/java'
CommandLine|contains: 'metabase'
filter_databases:
DestinationPort:
- 5432
- 3306
- 1433
- 1521
- 27017
- 443
- 80
condition: selection_process and not filter_databases
falsepositives:
- Connections to internal data sources on non-standard ports (baseline and exclude)
- SSO/OAuth identity provider callbacks
level: medium
KQL — Microsoft Sentinel Hunt
This query hunts web/proxy/WAF logs (ingested via CEF/Syslog or the IIS/Apache connector) for SQLi payloads aimed at Metabase endpoints, then correlates with large response volumes — a hallmark of data theft. Run it over at least 30 days to catch low-and-slow activity.
let sqli_patterns = dynamic(["' OR ", "' UNION ", "UNION SELECT", "UNION%20SELECT", "information_schema", "pg_catalog", "pg_sleep", "SLEEP(", "WAITFOR DELAY", "COPY ("]);
let metabase_endpoints = dynamic(["/api/dataset", "/api/card", "/api/native", "/api/query", "/api/database"]);
union isfuzzy=true
(CommonSecurityLog
| where TimeGenerated > ago(30d)
| where RequestURL has_any (metabase_endpoints)
| where RequestURL has_any (sqli_patterns) or AdditionalExtensions has_any (sqli_patterns)
| project TimeGenerated, SourceIP, RequestURL, RequestMethod, DeviceAction, SentBytes, ReceivedBytes, SourceHostName),
(Syslog
| where TimeGenerated > ago(30d)
| where SyslogMessage has_any (metabase_endpoints) and SyslogMessage has_any (sqli_patterns)
| project TimeGenerated, HostIP, Computer, SyslogMessage)
| summarize Requests = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated),
TotalBytesReceived = sum(tolong(ReceivedBytes))
by SourceIP, RequestURL
| where Requests > 5 or TotalBytesReceived > 10000000
| sort by LastSeen desc
A companion hunt for post-exploitation behavior on the Metabase host itself, if you are ingesting Linux process telemetry via the Defender or Sysmon-for-Linux agent:
DeviceProcessEvents
| where TimeGenerated > ago(14d)
| where InitiatingProcessCommandLine has "metabase" or InitiatingProcessFileName =~ "java"
| where FileName in~ ("sh", "bash", "dash", "curl", "wget", "nc", "ncat", "python", "python3", "base64")
| project TimeGenerated, DeviceName, FileName, ProcessCommandLine, InitiatingProcessCommandLine, AccountName
| sort by TimeGenerated desc
Velociraptor VQL Hunt
Use this artifact to sweep your Metabase hosts for suspicious child processes of the JVM and unexpected outbound sockets — the two highest-signal post-exploitation artifacts for this campaign.
-- Hunt: Metabase host post-exploitation artifacts (child processes + anomalous sockets)
SELECT Pid, Ppid, Name, Exe, CommandLine, Username, CreateTime
FROM pslist()
WHERE CommandLine =~ 'metabase'
OR Exe =~ 'java'
SELECT Pid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE Name =~ '(sh|bash|dash|curl|wget|nc|ncat|python3?|base64|id|whoami)$'
SELECT Pid, Name, Family, Type, LocalIP, LocalPort, RemoteIP, RemotePort, Status
FROM netstat()
WHERE Name =~ 'java'
AND Status =~ 'ESTABLISHED'
AND RemotePort NOT IN (80, 443, 1433, 1521, 3306, 5432, 27017)
Remediation
1. Patch Immediately
- Upgrade Metabase to the latest available release from the official project. Self-hosted deployments do not auto-update — pulling the latest Docker image or downloading the current JAR is a manual action that many teams forget for months.
- Docker: pull the current
metabase/metabaseimage and redeploy. - JAR: download the latest release and restart the service under your process manager (systemd, supervisor, etc.).
- Docker: pull the current
- Review the official release notes and security announcements at github.com/metabase/metabase/releases and the Metabase security documentation at metabase.com to identify the specific fixed version covering the SQL injection issue, and confirm you are at or above it.
2. Verify Patch State and Baseline Hardening
Run the following on each Metabase host to confirm version, exposure, and encryption-key hygiene:
# Confirm running Metabase version (API health endpoint returns version info)
curl -s http://localhost:3000/api/health && echo
curl -s http://localhost:3000/api/session/properties | grep -o '"version":"[^"]*"'
# If containerized, verify image tag and pull date
docker ps --filter "ancestor=metabase/metabase" --format '{{.Image}} {{.Status}}'
docker images metabase/metabase --format '{{.Tag}} {{.CreatedAt}}'
# Check whether MB_ENCRYPTION_SECRET_KEY is set to a non-default value
# (a default/absent key means stored DB credentials may be trivially recoverable)
env | grep MB_ENCRYPTION_SECRET_KEY
systemctl show metabase --property=Environment 2>/dev/null | grep -i encrypt
# Audit listening interfaces — Metabase should NOT be bound to 0.0.0.0 on an internet-facing host
ss -tlnp | grep -E '3000|java'
# Review recent application logs for SQL errors and suspicious query strings
journalctl -u metabase --since "30 days ago" | grep -iE 'error|exception|syntax|union|information_schema' | tail -n 100
3. Reduce the Blast Radius — This Is Where Most Organizations Fail
Even a fully patched Metabase remains a high-value target because of what it can reach. Apply least privilege to the database layer:
- Scope the Metabase service account to read-only on only the schemas it genuinely needs. It should never hold
SUPERUSER,DBO, DDL rights, or access to credential/payment tables that aren't required for analytics. - On PostgreSQL, explicitly revoke dangerous defaults:
REVOKE CREATE ON SCHEMA public FROM PUBLIC;and ensure the Metabase role cannot invoke server-side programming functions. - Rotate every database credential configured in Metabase if your instance was unpatched and internet-reachable at any point — assume the application database (and its stored connection strings) was read.
- Rotate
MB_ENCRYPTION_SECRET_KEYand re-encrypt stored credentials if there is any chance the application database was exposed.
4. Network Exposure Controls
- Remove Metabase from direct internet exposure. Place it behind authenticated access (SSO proxy, VPN, or ZTNA). Dashboard embedding does not require the admin interface or API to be world-reachable.
- Enforce IP allowlisting or mTLS at the reverse proxy for
/api/*administrative endpoints. - Egress-filter the Metabase host: it needs outbound access to its databases and (optionally) Metabase telemetry — nothing else. This single control would have materially impeded exfiltration in this campaign.
5. Assume Breach and Investigate
If your instance was running a vulnerable version and was internet-reachable:
- Review Metabase application logs, reverse-proxy logs, and database audit logs for the past 90 days for anomalous queries — especially bulk
SELECTs against customer tables,information_schemaenumeration, and queries outside business hours. - Check for new admin users, API keys, or modified data-source connections in the Metabase admin panel.
- If evidence of unauthorized access exists, invoke your IR plan and assess breach-notification obligations (the Framework and Tally disclosures both triggered customer notification — GDPR/CCPA/state-law clocks start at determination, not at patch).
6. Fix the Process Gap
These breaches happened because a known-vulnerable internet-facing service stayed unpatched. Ensure BI/analytics tooling is enrolled in your asset inventory and vulnerability management program, with owner-assigned SLAs for critical fixes — not left in a data-team blind spot.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.