
Technical analysis and proof of concept for CVE-2026-59827, a critical unsafe Java deserialization vulnerability in Metabase leading to remote code execution.
Severity: Critical (CVSS 9.9)
CVE: CVE-2026-59827
Advisory: GHSA-w95f-x9v9-wv36
Reporter: Matheus Gutierre (@Gutierre0x80)
Published: June 30, 2026
An authenticated user with access to native SQL queries on an H2 database can execute arbitrary Java code on the Metabase server via unsafe deserialization of Java objects returned from SELECT CAST(X'...' AS OTHER) queries.
The default Metabase installation includes an H2 sample database, making this vulnerability exploitable on all default deployments.
pip install requestsexploit.py:Ensure all prerequisites are installed and available in PATH:
# Install Python requests library
pip install requests
# Verify Java is available (OpenJDK 11+)
java -version
# Verify Python 3.7+
python3 --version
Then run the exploit from the poc/ directory:
cd poc/
python3 exploit.py <target_url> <username> <password> <command>
The script validates that clojure-1.12.3.jar and VarChainPayload.class exist in the working directory before execution.
python3 exploit.py <target_url> <username> <password> <command>
| Argument | Description | Example |
|---|---|---|
target_url | Metabase instance URL | http://127.0.0.1:3000 |
username | Authenticated user (admin or with native query access) | [email protected] |
password | User password | SecurePassword123! |
command | Shell command to execute | id or whoami |
python3 exploit.py http://127.0.0.1:3000 [email protected] Admin1234! "id > /tmp/pwned.txt"
The command is executed in the context of the Metabase process (typically the metabase user in Docker).
The H2 OTHER column type deserializes Java objects using a bare ObjectInputStream without JEP-290 filtering. This allows arbitrary class instantiation.
The payload uses a gadget chain based on Clojure's serializable classes (clojure.core$apply, clojure.lang.Var$Serialized, and PersistentList) combined with Java's PriorityQueue to trigger code execution via clojure.core/eval.
See writeup/analysis.md for full technical analysis.