Back to Intelligence

Metabase SQL Unpatched Remote-Admin Vulnerability: Detection, Containment, and Remediation Guide

SA
Security Arsenal Team
August 11, 2026
10 min read

Dark Reading reports a maximum-severity Metabase vulnerability with no CVE assigned yet that could allow malicious remote administrator access to the business-analytics platform and, critically, to downstream users that rely on the dashboards, embedded analytics, connected databases, and service credentials behind it. The operational concern is not just compromise of a BI server. It is compromise of the trust path between analysts, embedded customers, data sources, cached query results, API tokens, and whatever identities the Metabase service account can reach.

Because public technical detail is limited and no CVE is available in the source item, defenders should treat this as an unpatched, exploitation-plausible exposure: verify whether you run Metabase, determine whether it is reachable from untrusted networks, assume the admin plane is the target, and hunt for post-exploitation behavior rather than waiting for a clean signature. Do not invent a CVE or CVSS in change tickets. Track it as vendor-acknowledged/unpatched until Metabase publishes an advisory and fixed build.

Why the blast radius is wider than one server

Metabase often sits in a high-trust position: it holds database connection strings, service users, warehouse credentials, LDAP/SAML/OAuth configuration, email/webhook secrets, API keys, embedded-dashboard signing material, and sometimes cloud metadata adjacency if deployed in IaaS. A remote administrative condition can therefore cascade into:

  • Theft or modification of connected data-source credentials and SQL warehouse users.
  • Creation of rogue admins, API keys, public dashboards, embedding tokens, or password-reset flows.
  • Query manipulation against production replicas or analytics databases.
  • Abusing downstream users through altered dashboards, poisoned links, malicious questions/models, or data exfiltration via legitimate BI channels.
  • Persistence through scheduled jobs, webhooks, notification integrations, service accounts, or container restarts if the deployment is rebuilt from a tampered image/config.

Technical analysis: what we know and how to reason about it

Affected product: Metabase business-analytics / SQL analytics platform. Exact affected versions are not identified in the source item; treat all internet-reachable or recently unpatched self-hosted and cloud-managed-adjacent deployments as potentially exposed until the vendor advisory maps fixed versions.

CVE / CVSS: None provided in the source. Do not create a placeholder CVE. Severity is reported as maximum, but defenders should prioritize based on exposure and identity reach rather than an unpublished score.

Likely attack chain from a defender’s perspective:

  1. Attacker reaches the Metabase HTTP/S interface, reverse proxy, embedded endpoint, or management API.
  2. A flaw in the application path enables unauthorized or privileged administrative actions.
  3. The attacker uses admin-level control to create users/tokens, alter settings, add/modify data sources, run or schedule queries, or access application-managed secrets.
  4. Post-exploitation follows the host/runtime: the Metabase JVM or container process spawns unexpected children, makes unusual outbound connections, reads credential stores, writes new config, or connects to databases outside normal analytics windows.
  5. Downstream impact appears as changed dashboards, suspicious public links, unusual viewer activity, unexpected customer-facing content, or warehouse queries using Metabase service credentials.

Exploitation status: The source frames attacks as plausible with potentially wide blast radius; it does not provide a confirmed CISA KEV listing or a stable public IOC set. Treat internet-exposed instances as urgent, validate against CISA KEV and Metabase channels daily, and hunt using behavior-based detections below.

Detection and response

The highest-fidelity signal is not a magic string; it is Metabase doing things Metabase should not do: the Java/container runtime spawning shells, downloading tools, creating admin/API objects outside change control, connecting to new egress destinations, or touching secrets/config outside deployment windows.

YAML
---
title: Metabase Java Process Spawning Shell or Downloader on Windows
id: 8b2e5c91-3b6b-4f2b-9e7c-0a1d2e3f4a5b
status: experimental
description: Detects Windows hosts where a Java/Metabase runtime launches command interpreters, scripting engines, or download-capable binaries. Relevant to post-exploitation after remote admin compromise of a self-hosted Metabase server.
references:
  - https://attack.mitre.org/techniques/T1059/
  - https://attack.mitre.org/techniques/T1105/
author: Security Arsenal
date: 2026/05/22
tags:
  - attack.execution
  - attack.t1059
  - attack.command_and_control
  - attack.t1105
logsource:
  category: process_creation
  product: windows
detection:
  parent_metabase:
    ParentCommandLine|contains:
      - 'metabase'
      - 'metabase.jar'
  child_tools:
    Image|contains:
      - 'cmd.exe'
      - 'powershell.exe'
      - 'pwsh.exe'
      - 'wscript.exe'
      - 'cscript.exe'
      - 'certutil.exe'
      - 'bitsadmin.exe'
      - 'curl.exe'
      - 'wget.exe'
  condition: parent_metabase and child_tools
falsepositives:
  - Rare administrative maintenance performed interactively on the Metabase host
  - Deployment tooling that briefly shells out during upgrades; suppress by change window only
level: high
---
title: Metabase Container or JVM Spawning Shell on Linux
id: 1d7a6f45-9c31-4c5c-a6b2-77e0d1c2b3a4
status: experimental
description: Detects Linux Metabase JVM/container processes launching interactive shells or common transfer tools. This is a strong post-compromise indicator when tied to an analytics server rather than a developer workstation.
references:
  - https://attack.mitre.org/techniques/T1059.004/
  - https://attack.mitre.org/techniques/T1059.006/
author: Security Arsenal
date: 2026/05/22
tags:
  - attack.execution
  - attack.t1059.004
  - attack.t1059.006
logsource:
  category: process_creation
  product: linux
detection:
  selection_parent:
    ParentCommandLine|contains:
      - 'metabase'
      - 'java'
      - 'docker-entrypoint'
      - 'containerd-shim'
  selection_image:
    Image|endswith:
      - '/sh'
      - '/bash'
      - '/dash'
      - '/zsh'
      - '/python'
      - '/python3'
      - '/curl'
      - '/wget'
      - '/nc'
      - '/netcat'
  condition: selection_parent and selection_image
falsepositives:
  - Container health checks or init scripts
  - Break-glass troubleshooting on the analytics host
level: high
---
title: Metabase Runtime Initiating Rare Outbound Connection
id: 5f0d2b88-1a94-4de9-a371-9a9b8c7d6e5f
status: experimental
description: Detects Metabase/JVM processes initiating outbound connections to high-risk or uncommon destinations. Use as a medium-severity hunt signal correlated with admin changes, new tokens, or process execution alerts.
references:
  - https://attack.mitre.org/techniques/T1071/
  - https://attack.mitre.org/techniques/T1572/
author: Security Arsenal
date: 2026/05/22
tags:
  - attack.command_and_control
  - attack.t1071
  - attack.exfiltration
  - attack.t1041
logsource:
  category: network_connection
  product: linux
detection:
  selection_image:
    Image|endswith:
      - '/java'
      - '/docker'
      - '/containerd'
  selection_cmd:
    CommandLine|contains:
      - 'metabase'
  suspicious_ports:
    DestinationPort:
      - 4444
      - 5555
      - 6667
      - 9001
      - 1337
      - 2323
      - 31337
  condition: selection_image and selection_cmd and suspicious_ports
falsepositives:
  - Misconfigured integrations or niche webhooks using nonstandard ports
level: medium
KQL — Microsoft Sentinel / Defender
let window = 7d;
let shells = dynamic(["cmd.exe","powershell.exe","pwsh.exe","wscript.exe","cscript.exe","certutil.exe","bitsadmin.exe","curl.exe","wget.exe","sh","bash","python","python3","nc","netcat"]);
let suspiciousPorts = dynamic([4444,5555,6667,9001,1337,2323,31337]);
let metabaseProc = DeviceProcessEvents
| where TimeGenerated >= ago(window)
| where ProcessCommandLine has_any ("metabase","metabase.jar") or InitiatingProcessCommandLine has_any ("metabase","metabase.jar");
let childExec = metabaseProc
| where FileName in~ (shells) or ProcessCommandLine has_any ("Invoke-","iex","wget ","curl ","bash -c","sh -c","nc ","python -c");
let egress = DeviceNetworkEvents
| where TimeGenerated >= ago(window)
| where InitiatingProcessCommandLine has_any ("metabase","metabase.jar") or InitiatingProcessFileName =~ "java"
| where RemotePort in (suspiciousPorts) or (RemoteIPType == "Public" and RemotePort !in (80,443));
let webSignals = CommonSecurityLog
| where TimeGenerated >= ago(window)
| where RequestURL has_any ("/api/", "metabase") or ApplicationProtocol =~ "http"
| where RequestURL has_any ("/api/user", "/api/session", "/api/setup", "/api/database", "/api/permissions", "/api/setting", "/api/notify", "/api/embed", "/api/card", "/api/dashboard")
| where DeviceAction !in ("Allow","Allowed") or SourceIP !in (dynamic(["10.0.0.0/8","172.16.0.0/12","192.168.0.0/16"]));
union childExec, egress, webSignals
| project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessCommandLine, RemoteIP, RemotePort, SourceIP, DestinationIP, RequestURL, RequestMethod, DeviceAction, ReceivedBytes, SentBytes
| order by TimeGenerated desc;
VQL — Velociraptor
-- Hunt Metabase servers for JVM/container runtime with suspicious children or public egress
LET proc = SELECT Pid, Ppid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE CommandLine =~ '(?i)metabase|metabase\.jar|java'
   OR Exe =~ '(?i)(bash|sh|python|curl|wget|nc|netcat|powershell|cmd)(\.exe)?$'

LET conns = SELECT Pid, Family, Type, LocalAddr, LocalPort, RemoteAddr, RemotePort, State, Name
FROM netstat()
WHERE RemotePort in (4444,5555,6667,9001,1337,2323,31337)
   OR (State =~ 'ESTABLISHED' AND RemoteAddr !~ '^(10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.|192\.168\.|127\.|::1|fc|fd)')

SELECT proc.Pid AS Pid,
       proc.Ppid AS Ppid,
       proc.Name AS ProcessName,
       proc.Username AS Username,
       proc.CommandLine AS CommandLine,
       conns.RemoteAddr AS RemoteAddr,
       conns.RemotePort AS RemotePort,
       conns.State AS ConnState
FROM proc
LEFT JOIN conns ON proc.Pid = conns.Pid
ORDER BY Pid
Bash / Shell
#!/usr/bin/env bash
set -euo pipefail

# Emergency verification and hardening for self-hosted Metabase pending vendor fixed-version guidance.
# Run as root on the Metabase host or adapted for container/Kubernetes hosts.

echo '[*] Inventory Metabase processes and listeners'
ps -eo pid,ppid,user,cmd | grep -Ei 'metabase|metabase\.jar|java' | grep -v grep || true
ss -lntp | grep -E ':(80|443|3000|8080|8443)|metabase|java' || true

echo '[*] Check whether service is exposed beyond localhost/VPN'
hostname -I || true
ss -lntp | awk 'NR>1 {print $4, $7}' | grep -E '0\.0\.0\.0|\[::\]' || true

echo '[*] Capture volatile evidence before changes'
ts="$(date -u +%Y%m%dT%H%M%SZ)"; out="/var/tmp/metabase_ir_$ts"; mkdir -p "$out"
ps auxww > "$out/ps.txt"
ss -tanp > "$out/netstat.txt"
find /var/log /opt /srv /home -maxdepth 4 -type f \( -iname '*metabase*log*' -o -iname 'metabase.db.mv.db' -o -iname '*.jar' \) 2>/dev/null > "$out/metabase_artifacts.txt"
cp -a /etc/metabase* "$out/" 2>/dev/null || true

echo '[*] Immediate containment switches - review before running in production'
read -r -p 'Apply containment now? type CONTAIN to proceed: ' ans
if [[ "$ans" == "CONTAIN" ]]; then
  if command -v ufw >/dev/null 2>&1; then
    ufw deny in to any port 3000 proto tcp comment 'IR metabase containment' || true
    ufw deny in to any port 8080 proto tcp comment 'IR metabase containment' || true
  fi
  systemctl stop metabase 2>/dev/null || true
  docker ps --format '{{.Names}}' | grep -Ei '^metabase$|metabase' | xargs -r docker pause || true
fi

echo '[*] Rotate high-risk secrets if compromise is suspected'
cat <<'EOF'
Manual rotation checklist:
- Metabase admin passwords, local users, API keys, personal access tokens, session secrets.
- Data-source usernames/passwords and warehouse service accounts used by Metabase.
- SMTP/webhook/Slack/notification tokens, LDAP bind accounts, SAML/OAuth client secrets.
- Embedded dashboard signing keys and public sharing links.
- Cloud instance role credentials if the host had metadata/IMDS reachability.
EOF

echo '[*] Report egress destinations seen during lookback'
journalctl --since '14 days ago' -u metabase --no-pager 2>/dev/null | grep -Ei 'http|jdbc|error|exception|token|setup|admin|database|user' | tail -n 200 > "$out/metabase_journal_tail.txt" || true
echo "Evidence bundle: $out"

Remediation and risk reduction

  1. Establish exposure now. Inventory every Metabase instance, container image tag, reverse proxy route, embedded deployment, sandbox, analytics node, and forgotten QA instance. Confirm whether any path is reachable from the internet, partner networks, customer portals, or broad internal user communities.
  2. Isolate until patched. If the service is internet-facing and business-acceptable downtime exists, take it offline or place it behind VPN/SSO with strict source-IP allowlists. Block direct access to the application port; require authenticated reverse proxy with MFA at the identity layer.
  3. Apply vendor updates immediately when released. Pull only from official Metabase release channels and the project security advisory/GitHub releases. Do not apply community patches blindly. Record fixed version, digest, deployment time, and rollback plan. Recheck CISA KEV after disclosure; if added, treat remediation deadlines as mandatory for applicable environments.
  4. Temporarily reduce admin-plane attack surface. Disable public signup if not required, restrict setup/admin routes at the proxy, require SSO/MFA for admins, disable anonymous/public dashboards and embedding where feasible, and separate the Metabase database from the application network segment.
  5. Rotate credentials on suspicion. Prioritize data-source passwords, warehouse users, API tokens, OAuth/SAML secrets, SMTP/webhook tokens, LDAP binds, embedding keys, and any cloud role reachable from the host. Assume downstream consumers may have seen manipulated content and notify owners of shared/public dashboards.
  6. Constrain egress and identity. The Metabase host should only reach approved databases, IdPs, SMTP, update endpoints, and required integrations. Deny broad internet egress from analytics servers. Ensure the Metabase service principal has least privilege and cannot read production secrets or modify IAM.
  7. Validate integrity before reconnecting downstream users. Review admin/user creation, sessions, database connections, permissions groups, public links, subscriptions, alerts, model/question changes, dashboard diffs, scheduled tasks, and query audit logs. Rebuild from trusted image/config where post-exploitation is confirmed.
  8. Add durable detections. Alert on Metabase/JVM child processes, first-seen egress, admin actions outside change windows, creation of API keys/users, new public dashboard links, spikes in failed then successful admin authentication, and warehouse queries using Metabase credentials outside baseline schedules.

If you need outside validation, run a targeted purple-team: emulate unauthorized admin access against a staging Metabase node, verify proxy logging captures API events, confirm EDR sees Java child processes, and prove credential rotation actually breaks stolen sessions before declaring recovery complete.

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.