Skip to content

CVE-2026-59826: Verified Repro With Script Download

CVE-2026-59826: Metabase arbitrary code execution via unsafe H2 connection property validation bypass

CVE-2026-59826 is verified against metabase/metabase · github. This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00293.

REPRO-2026-00293 metabase/metabase · github Variant found Known vulnerability Jul 17, 2026 CVE entry ↗ .txt
Severity
CRITICAL
CVSS
9.1
Confidence
HIGH
Reproduced in
92m 57s
Tool calls
348
Spend
$27.81
01 · Overview

What Is CVE-2026-59826?

CVE-2026-59826 is a critical arbitrary code execution vulnerability in Metabase. An authenticated administrator can register a crafted H2 database connection whose unsafe properties are not validated, causing arbitrary Java code to run on the Metabase server. Pruva reproduced it end-to-end (reproduction REPRO-2026-00293).

02 · Severity & CVSS

CVE-2026-59826 Severity & CVSS Score

CVE-2026-59826 is rated critical severity, with a CVSS base score of 9.1 out of 10.

CRITICAL threat level
9.1 / 10 CVSS base
Weakness CWE-94 — Improper Control of Generation of Code ('Code Injection')

Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.

How to Reproduce CVE-2026-59826

$ pruva-verify REPRO-2026-00293
or curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00293/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-59826

Remote code execution — reproduced
  • reached the target end-to-end
  • full exploit chain demonstrated
  • on the real production code path
  • high confidence
  • the upstream fix blocks the same trigger
Trigger

H2 database connection string in POST /api/ee/database-routing/destination-database details.db

Attack chain
  1. POST /api/ee/database-routing/destination-database then POST /api/dataset opens the persisted H2 destination
Runnable proof: reproduction_steps.sh
Captured evidence: fixed commit 74032e5 relevant diffvulnerable loader evidencefixed loader evidencefixed tag variant code anchorsvulnerable metabasefixed metabasefixed metabase
Variants tested

No distinct bypass or alternate trigger was confirmed. Candidate database-detail entry points outside the parent database-routing destination endpoint were blocked, guarded, or unavailable in Metabase Enterprise v1.61.1/v1.61.2 runtime tests and fixed-tag source review.

How the agent worked 884 events · 348 tool calls · 1h 33m
1h 33mDuration
348Tool calls
258Reasoning steps
884Events
23Dead-ends
Agent activity over 1h 33m
Policy
1
Support
20
Repro
543
Variant
315
Verify
1
0:0092:57

Root Cause and Exploit Chain for CVE-2026-59826

Versions: reported as >= 1.55.0 < 1.58.15.1, >= 1.59.0 < 1.59.12, >= 1.60.0 < 1.60.6.3, and >= 1.61.0 < 1.61.2.
  • Affected versions: reported as >= 1.55.0 < 1.58.15.1, >= 1.59.0 < 1.59.12, >= 1.60.0 < 1.60.6.3, and >= 1.61.0 < 1.61.2.
  • Risk level and consequences: critical. An authenticated administrator can create a crafted H2 destination database, then cause Metabase to open it. H2 executes SQL embedded in connection properties, which can be escalated to arbitrary Java/code execution primitives supported by H2. The reproduction demonstrates server-side attacker-controlled file creation from inside the Metabase JVM.

Impact Parity

  • Disclosed/claimed maximum impact: arbitrary code execution / arbitrary Java code execution on the Metabase server by an authenticated administrator.
  • Reproduced impact from this run: the real Metabase Enterprise product accepted a crafted H2 destination through the remote API, later opened the persisted connection through the /api/dataset product endpoint, and H2 executed attacker-controlled SQL that wrote marker files inside the Metabase container in two independent vulnerable attempts.
  • Parity: full.
  • Not demonstrated: the proof stops at deterministic server-side H2 SQL execution/file-write markers rather than spawning an OS shell. This is the same unsafe H2 execution mechanism underlying the code-execution claim; the fixed-version negative control demonstrates the intended validation blocks this primitive before persistence.

Root Cause

The vulnerable endpoint persisted database-routing destinations without validating details that were unsafe to store. The standard H2 connection path already had logic to reject unsupported H2 data-warehouse use and dangerous connection properties during connection testing, and the H2 connection builder stripped URL options whose key was INIT. However, POST /api/ee/database-routing/destination-database was designed not to test reachability at creation time, and in the vulnerable version it also skipped an unconditional validation pass over details before insertion.

The bypass used in this reproduction relies on H2's escaped semicolon syntax inside a connection property value. The payload stores a db value like:

file:/plugins/sample-database.db;USER=GUEST;PASSWORD=guest;TRACE_LEVEL_SYSTEM_OUT=1\;CALL CSVWRITE('/tmp/pruva_vuln_attempt_1_marker.csv','SELECT 598261')=0

Metabase v1.61.1 persisted this string via the destination-database API. When a later /api/dataset request caused Metabase to open that database, H2 interpreted the escaped semicolon and executed the injected CALL CSVWRITE(...) statement. The fixed commit 74032e5e0a5a70dc45a6a744d37b9ba24eee8d01 introduces driver/validate-db-details! and calls it from the destination database creation path, so H2 details are rejected before persistence. The reproduction script records this fix diff in bundle/logs/fixed_commit_74032e5_relevant_diff.log.

Reproduction Steps

  1. Run bundle/repro/reproduction_steps.sh from the bundle root, or with PRUVA_ROOT pointing at the bundle directory.
  2. The script:
    • reuses/clones the Metabase repository in the prepared project cache and records the fixed commit and parent commit;
    • starts real Metabase Enterprise Docker images metabase/metabase-enterprise:v1.61.1 and metabase/metabase-enterprise:v1.61.2;
    • initializes an administrator account through /api/setup and authenticates through /api/session;
    • enables database routing through the real Enterprise API;
    • sends the malicious destination database creation request to /api/ee/database-routing/destination-database twice against the vulnerable product;
    • forces the persisted destination connection through POST /api/dataset and verifies marker files created inside the vulnerable Metabase container;
    • sends the same payload twice to the fixed product and verifies it is rejected.
  3. Expected evidence: bundle/logs/reproduction_steps.log should show two vulnerable marker creations and two fixed rejections. bundle/repro/runtime_manifest.json should have service_started=true, healthcheck_passed=true, and target_path_reached=true.

Evidence

  • Primary runtime log: bundle/logs/reproduction_steps.log.
  • Runtime manifest: bundle/repro/runtime_manifest.json.
  • Vulnerable product logs: bundle/logs/vulnerable_metabase.log.
  • Fixed product logs: bundle/logs/fixed_metabase.log.
  • Request/response artifacts:
    • bundle/logs/vuln_attempt_1_api.request.json
    • bundle/logs/vuln_attempt_1_api.response.json
    • bundle/logs/vuln_attempt_1_api.query_response.json
    • bundle/logs/vuln_attempt_2_api.request.json
    • bundle/logs/vuln_attempt_2_api.response.json
    • bundle/logs/vuln_attempt_2_api.query_response.json
    • bundle/logs/fixed_attempt_1_api.request.json
    • bundle/logs/fixed_attempt_1_api.response.json
    • bundle/logs/fixed_attempt_2_api.request.json
    • bundle/logs/fixed_attempt_2_api.response.json
  • Marker artifacts copied out of the vulnerable container:
    • bundle/artifacts/metabase-cve-2026-59826/vuln_attempt_1_marker.txt contains the value written by H2 SQL execution.
    • bundle/artifacts/metabase-cve-2026-59826/vuln_attempt_2_marker.txt contains the value written by the second H2 SQL execution.
  • Fixed-version evidence: the final run logged fixed attempt 1 destination API HTTP status=400 and fixed attempt 2 destination API HTTP status=400, both with H2 is not supported as a data warehouse, confirming the new validation path blocked H2 details before execution.
  • Source/patch evidence:
    • bundle/logs/fixed_commit_74032e5.patch_summary.log
    • bundle/logs/fixed_commit_74032e5_relevant_diff.log

Key excerpts from the successful final run include:

vuln attempt 1 destination API HTTP status=200
vuln attempt 1 dataset API HTTP status=202 destination_id=2
vuln attempt 1 marker created inside Metabase container: "598261" "598261"
vuln attempt 2 destination API HTTP status=200
vuln attempt 2 dataset API HTTP status=202 destination_id=3
vuln attempt 2 marker created inside Metabase container: "598262" "598262"
fixed attempt 1 destination API HTTP status=400 body={"pruva-cve-59826-fixed-1":{"message":"H2 is not supported as a data warehouse"}}
fixed attempt 1 was blocked by fixed validation as expected
fixed attempt 2 destination API HTTP status=400 body={"pruva-cve-59826-fixed-2":{"message":"H2 is not supported as a data warehouse"}}
fixed attempt 2 was blocked by fixed validation as expected

Environment details: Docker was used to run the vendor Metabase Enterprise images. The script starts the product on localhost ports within the worker network and captures product loader/cmdline evidence in bundle/logs/vulnerable_loader_evidence.log and bundle/logs/fixed_loader_evidence.log. Because database-routing is an Enterprise feature and external license validation is not available in the isolated repro environment, the script starts the product through a minimal Clojure wrapper that only stubs the premium-token check to enable the database-routing feature; the vulnerable API, H2 driver, connection handling, and fixed validation code paths remain the real product code from the vendor images.

Recommendations / Next Steps

  • Upgrade Metabase to a fixed version: 1.58.15.1, 1.59.12, 1.60.6.3/1.60.7, 1.61.2, or later.
  • Keep driver/validate-db-details! checks independent of reachability testing. Creation paths that intentionally skip connection tests must still reject unsafe details before persistence.
  • Add regression tests for all database creation/persistence paths, including destination databases, write/admin connection details, serialization/import paths, and any route that stores H2 details without immediately connecting.
  • Specifically test H2 escaped-semicolon property values, uppercase/lowercase property names, and non-INIT properties whose values contain semicolon-delimited SQL.

Additional Notes

  • Idempotency confirmation: bundle/repro/reproduction_steps.sh was run successfully twice consecutively after the final fix to the script. Each successful run starts fresh vulnerable and fixed containers, initializes fresh application databases, performs two vulnerable attempts, and performs two fixed negative-control attempts.
  • The script references the fixed commit 74032e5e0a5a70dc45a6a744d37b9ba24eee8d01 directly and resolves its parent as the vulnerable source identity, satisfying the fixed-commit anchoring rule.
  • The proof demonstrates the strongest runtime surface available for this claim: real HTTP API requests against running Metabase Enterprise containers. The wrapper used to bypass offline license validation is limited to feature gating and is not a mock of the vulnerable endpoint or H2 execution path.

Variant Analysis & Alternative Triggers for CVE-2026-59826

Fix Coverage / Assumptions

The original fix relies on the invariant that every code path that persists H2 connection details without testing reachability must still run a validation-only safety check before storing those details. The fixed commit is 74032e5e0a5a70dc45a6a744d37b9ba24eee8d01.

The fix explicitly covers the vulnerable database-routing path:

  • enterprise/backend/src/metabase_enterprise/database_routing/api.clj, POST /api/ee/database-routing/destination-database: the fixed path iterates over each submitted destination, calls driver/validate-db-details! with the router database engine and submitted destination details, and returns HTTP 400 for any thrown validation error before t2/insert-returning-instances! :model/Database persists the destination.
  • src/metabase/driver/h2.clj: the H2 driver's existing safety checks were moved into driver/validate-db-details! :h2. This method rejects H2 as a data warehouse when *allow-testing-h2-connections* is false, rejects parsed INIT properties, and rejects malicious property values containing semicolons or scripting-language markers. driver/can-connect? :h2 now delegates to the same validation method.

Important non-destination paths were inspected and/or tested:

  • Normal database creation/update (POST /api/database, PUT /api/database/:id) already calls test-connection-details / test-database-connection, which reaches driver/can-connect? :h2 and therefore the same H2 validation. Runtime checks confirmed both vulnerable v1.61.1 and fixed v1.61.2 reject unsafe H2 creation with H2 is not supported as a data warehouse.
  • Serialization import has a dedicated assert-not-h2! guard in src/metabase/warehouses/models/database.clj, rejecting imported Database entities whose engine is H2 before the generic serdes load path can persist them. Runtime API probing did not reach a successful import path in either tested image; source inspection shows the H2-specific guard exists in both v1.61.1 and v1.61.2.
  • Runtime /api/ee/advanced-config upload was not available in the tested v1.61.1/v1.61.2 product images. Boot/config-file import source code also calls driver.u/can-connect-with-details? before creating or updating non-deletion database entries, which would hit H2 validation.

The fix does not add a global database-model before-insert hook for validate-db-details!; instead it patches the known unsafe destination-database endpoint and relies on other entry points' existing validation/guard logic. The variant search therefore focused on other remote/admin entry points that can write :model/Database :details.

Variant / Alternate Trigger

No confirmed variant/bypass was found. The tested candidate entry points were:

  1. POST /api/database with an H2 details.db value containing the same escaped-semicolon SQL primitive used in the parent reproduction. Both v1.61.1 and v1.61.2 returned HTTP 400 with H2 is not supported as a data warehouse; no database row was created and no marker file was written.
  2. POST /api/ee/serialization/import with a crafted serialization archive containing a Database YAML entity with engine: h2 and the same malicious details.db value. The HTTP import request failed in both tested images before importing the database. Source review of the exact fixed tag and vulnerable tag shows serdes/load-one! "Database" calls assert-not-h2!, which rejects H2 database entities during import.
  3. Probe for POST /api/ee/advanced-config/ runtime upload. The endpoint returned HTTP 404 in both tested v1.61.1 and v1.61.2 images. Source review of the config-file database loader also shows it tests connectivity before database creation/update.

Relevant code paths and anchors:

  • Parent fixed sink coverage: enterprise/backend/src/metabase_enterprise/database_routing/api.clj, destination validation and insertion logic around lines 38-63 in the fixed tag.

  • H2 validation sink: src/metabase/driver/h2.clj, driver/validate-db-details! :h2 and driver/can-connect? :h2 around lines 118-140 in the fixed tag.

  • Normal database API: src/metabase/warehouses/api.clj, POST /api/database and PUT /api/database/:id call connection testing around lines 864-898 and 967-1011 in the fixed tag.

  • Config-file database loader: enterprise/backend/src/metabase_enterprise/advanced_config/file/databases.clj, driver.u/can-connect-with-details? before insert/update around lines 79-89 in the fixed tag.

  • Serialization import guard: src/metabase/warehouses/models/database.clj, assert-not-h2! and serdes/load-one! "Database" around lines 573-586 in the fixed tag.

  • Tested versions: vulnerable image metabase/metabase-enterprise:v1.61.1 and fixed image metabase/metabase-enterprise:v1.61.2.

  • Variant-stage outcome: no additional exploitable component was confirmed. The parent impact remains critical for vulnerable database-routing builds, but no separate fixed-version bypass impact was reproduced.

Impact Parity

  • Disclosed/claimed maximum impact for the parent: arbitrary code execution / arbitrary Java code execution on the Metabase server by an authenticated administrator through unsafe H2 connection properties.
  • Reproduced impact from this variant run: none for a distinct variant. The variant script executed bounded alternate-entrypoint checks and observed rejection/unavailability rather than server-side marker creation.
  • Parity: none for a distinct variant/bypass.
  • Not demonstrated: no fixed-version code execution, file write, or persisted unsafe H2 database through an alternate route was demonstrated.

Root Cause

The parent root cause was not a flaw in H2 parsing alone; it was a Metabase trust-boundary problem where an authenticated administrator could send H2 details over a remote API path that persisted them without invoking the existing safety gate. When the persisted destination database was later opened through /api/dataset, H2 interpreted an escaped semicolon in a non-INIT property value and executed attacker-controlled SQL.

The fixed commit 74032e5e0a5a70dc45a6a744d37b9ba24eee8d01 closes the specific missing-validation path by introducing/using driver/validate-db-details! and invoking it in POST /api/ee/database-routing/destination-database. The variant search attempted to find another remote/admin entry point that persisted the same unsafe details without validation. The candidate paths either already funneled into driver/can-connect? :h2/validate-db-details!, had an independent H2 rejection guard, or were unavailable in the tested fixed product.

Reproduction Steps

  1. Run bundle/vuln_variant/reproduction_steps.sh from the bundle root, or set PRUVA_ROOT to the bundle directory and run the script from any directory.
  2. The script starts real Metabase Enterprise Docker images v1.61.1 and v1.61.2, initializes an admin account, and performs side-by-side candidate checks against both versions:
    • POST /api/database with the malicious H2 escaped-semicolon connection string.
    • POST /api/ee/serialization/import with a crafted H2 Database serialization archive.
    • POST /api/ee/advanced-config/ endpoint availability probe.
  3. Expected evidence for this negative result: the script completes without crashing and exits 1. Logs show both normal database creation requests are rejected, serialization import does not create a marker, and the advanced-config endpoint is unavailable in both tested images.

Evidence

Primary evidence locations:

  • bundle/logs/vuln_variant/reproduction_steps.log — full runtime log for the last variant run.
  • bundle/vuln_variant/runtime_manifest.json — structured runtime manifest for the variant checks.
  • bundle/logs/vuln_variant/source_versions.txt — source/image identity for the tested vulnerable and fixed targets.
  • bundle/logs/vuln_variant/fixed_tag_variant_code_anchors.log — source anchor excerpts for fix coverage and candidate guards.
  • Candidate request/response logs:
    • bundle/logs/vuln_variant/vuln_database_create.request.json
    • bundle/logs/vuln_variant/vuln_database_create.response.json
    • bundle/logs/vuln_variant/fixed_database_create.request.json
    • bundle/logs/vuln_variant/fixed_database_create.response.json
    • bundle/logs/vuln_variant/vuln_serialization_import.response.txt
    • bundle/logs/vuln_variant/fixed_serialization_import.response.txt
    • bundle/logs/vuln_variant/vuln_advanced_config_probe.response.txt
    • bundle/logs/vuln_variant/fixed_advanced_config_probe.response.txt

Key runtime excerpts from the verified script runs:

vuln candidate 1 status=400 body={"message":"H2 is not supported as a data warehouse"}
fixed candidate 1 status=400 body={"message":"H2 is not supported as a data warehouse"}
vuln candidate 2 status=500 body={"via":[{"type":"java.lang.ClassCastException", ...
fixed candidate 2 status=500 body={"via":[{"type":"java.lang.ClassCastException", ...
vuln advanced-config probe status=404 body="API endpoint does not exist."
fixed advanced-config probe status=404 body="API endpoint does not exist."
No variant bypass confirmed. Candidate entry points were blocked or unavailable on the fixed product.

Source identity from source_versions.txt:

vulnerable_image=metabase/metabase-enterprise:v1.61.1
vulnerable_tag_commit=770276bdddee78aed8ee0f75cdddd61a744664d4
fixed_image=metabase/metabase-enterprise:v1.61.2
fixed_tag_commit=74032e5e0a5a70dc45a6a744d37b9ba24eee8d01
patch_commit=74032e5e0a5a70dc45a6a744d37b9ba24eee8d01

Environment details: Docker was used to run vendor Metabase Enterprise images. As in the parent reproduction, the script starts Metabase through a small wrapper that stubs premium token validation only so Enterprise routes can be exercised in the isolated environment; product API handlers, H2 driver code, and connection validation remain from the vendor images.

Recommendations / Next Steps

  • Keep the current destination-database fix, because it correctly adds validation to the previously missing persistence path.
  • For defense in depth, consider adding a model-level or centralized persistence guard for database details, e.g. invoking driver/validate-db-details! in a safe before-insert/before-update path for :model/Database whenever details originate from a user/admin-controlled API or import surface. Internal/sample-database flows that legitimately need H2 can explicitly bind the existing H2 testing allow flag.
  • Add regression tests covering every :model/Database write surface that accepts external/admin input: database-routing destinations, normal database create/update, config-file database initialization, and serialization import.
  • Ensure serialization import failures surface the intended H2-specific rejection rather than unrelated logging failures in the tested environment, so future security regression checks can verify assert-not-h2! directly through the API.

Additional Notes

  • The variant reproduction script was run twice successfully. Both runs completed without crashing and exited 1, which is the expected negative-result code for this stage.
  • Fewer than three runtime-confirmed candidates were available because the normal database API and serialization import were the only distinct remote/admin database-detail entry points present in the tested images besides the parent database-routing path; the runtime advanced-config upload endpoint referenced by later source code was not present in v1.61.1/v1.61.2 images.
  • This report does not claim a new vulnerability. It documents bounded testing and source review showing no fixed-version bypass was confirmed.

CVE-2026-59826 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired. Phases: support · claim contract · reproduction · judge · variant analysis

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:002:31
0:00
session startedgpt-5.5 · CVE-2026-59826 · REPRO-20
0:07
0:08
web search
0:12
0:45
0:47
web search
0:54
0:54
0:55
1:05
1:05
1:06
web search
2:01
2:01
extract_facts
no facts extracted
2:02
2:02
supportclaim_contract
2:09
2:09
2:09
2:11
2:14
2:14
2:14
2:17
2:28
web search
2:28
$docker ps >/tmp/docker_ps_out 2>/tmp/docker_ps_err; ec=$?; echo "EXIT=$ec"; cat /tmp/docker_ps_out; cat /tmp/docker_ps_err
{"cwd":"/data/pruva/runs/aaea348a-f59e-47ad-b750-28ed79e9d8d6","duration_ms":77,"exit_code":0,"stderr":"","stdout":"EXIT=0\nCONTAINER ID   IMAGE                                           COMMAND                   CREATED        STATUS                  PORTS                                                                   NAMES\n7c52a656b9f8   platform-pruva-api                              \"/app/pruva-api --po…\"    9 hours ago    Up 9 hours              0.0.0.0:4000->4000/tcp, [::]:4000->4000/tcp                             platform-pruva-api-1\n3e2c54f63380   athena-pruva-worker-sandbox:latest              \"pruva-worker --back…\"    9 hours ago    Up 9 hours (healthy)                                                                            athena-pruva-worker-kimi27-gpt55\nd9ee0df8412a   athena-pruva-worker-sandbox:latest              \"pruva-worker --back…\"    9 hours ago    Up 9 hours (healthy)                                                                            athena-pruva-worker-glm52-gpt55-repro2\n82edfb53ee91   athena-pruva-worker-sandbox:latest              \"pruva-worker --back…\"    9 hours ago    Up 9 hours (healthy)                                         … [truncated]
2:28
2:31

Artifacts and Evidence for CVE-2026-59826

Scripts, logs, diffs, and output captured during the reproduction.

bundle/logs/fixed_commit_74032e5_relevant_diff.log4.8 KB
bundle/logs/vulnerable_loader_evidence.log0.6 KB
bundle/logs/fixed_loader_evidence.log0.6 KB
bundle/vuln_variant/source_identity.json1.0 KB
bundle/vuln_variant/root_cause_equivalence.json1.0 KB
bundle/logs/vuln_variant/fixed_tag_variant_code_anchors.log21.4 KB
bundle/repro/reproduction_steps.sh16.5 KB
bundle/repro/rca_report.md9.4 KB
bundle/repro/validation_verdict.json0.9 KB
bundle/repro/runtime_manifest.json1.4 KB
bundle/logs/reproduction_steps.log7.7 KB
bundle/logs/vuln_attempt_1_api.request.json0.3 KB
bundle/logs/vuln_attempt_1_api.response.json1.9 KB
bundle/logs/vuln_attempt_1_api.query_response.json1.5 KB
bundle/logs/vuln_attempt_2_api.request.json0.3 KB
bundle/logs/vuln_attempt_2_api.response.json1.9 KB
bundle/logs/vuln_attempt_2_api.query_response.json1.5 KB
bundle/logs/fixed_attempt_1_api.request.json0.3 KB
bundle/logs/fixed_attempt_1_api.response.json0.1 KB
bundle/logs/fixed_attempt_2_api.request.json0.3 KB
bundle/logs/fixed_attempt_2_api.response.json0.1 KB
bundle/artifacts/metabase-cve-2026-59826/vuln_attempt_1_marker.txt0.0 KB
bundle/artifacts/metabase-cve-2026-59826/vuln_attempt_2_marker.txt0.0 KB
bundle/logs/vulnerable_metabase.log388.9 KB
bundle/logs/fixed_metabase.log387.6 KB
bundle/vuln_variant/reproduction_steps.sh17.9 KB
bundle/vuln_variant/rca_report.md12.1 KB
bundle/vuln_variant/patch_analysis.md8.9 KB
bundle/vuln_variant/variant_manifest.json3.9 KB
bundle/vuln_variant/validation_verdict.json2.6 KB
bundle/vuln_variant/runtime_manifest.json1.3 KB
bundle/logs/vuln_variant/reproduction_steps.log4.5 KB
bundle/logs/vuln_variant/source_versions.txt0.3 KB
bundle/logs/vuln_variant/vuln_database_create.response.json0.1 KB
bundle/logs/vuln_variant/fixed_database_create.response.json0.1 KB
bundle/logs/vuln_variant/vuln_metabase.log417.0 KB
bundle/logs/vuln_variant/fixed_metabase.log416.7 KB
bundle/logs/vuln_variant/vuln_database_create.request.json0.3 KB
bundle/logs/vuln_variant/fixed_database_create.request.json0.3 KB
bundle/logs/vuln_variant/vuln_serialization_import.response.txt15.0 KB
bundle/logs/vuln_variant/fixed_serialization_import.response.txt15.0 KB
bundle/logs/vuln_variant/vuln_advanced_config_probe.response.txt0.0 KB
bundle/logs/vuln_variant/fixed_advanced_config_probe.response.txt0.0 KB
08 · How to Fix

How to Fix CVE-2026-59826

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-59826 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-59826

How does the CVE-2026-59826 H2 code execution work?

In vulnerable Metabase Enterprise, POST /api/ee/database-routing/destination-database created an H2 destination database without invoking the H2 driver's unsafe-detail validation. A crafted H2 connection string using an escaped semicolon inside a non-INIT connection property is persisted, and a later query through POST /api/dataset opens that destination and executes attacker-controlled H2 SQL inside the Metabase JVM.

Who can exploit CVE-2026-59826?

Exploitation requires an authenticated administrator on the Metabase instance — it is a privileged-attacker code-execution bug, not a pre-auth one. Pruva verified it against Metabase v1.61.1 with high confidence.

Which versions of Metabase are affected by CVE-2026-59826, and where is it fixed?

Affected ranges are >= 1.55.0 < 1.58.15.1, >= 1.59.0 < 1.59.12, >= 1.60.0 < 1.60.6.3, and >= 1.61.0 < 1.61.2. It is fixed in 1.58.15.1, 1.59.12, 1.60.6.3, and 1.61.2 — upgrade to the corresponding fixed release for your branch.

How can I reproduce CVE-2026-59826?

Download the verified script from this page and run it against Metabase v1.61.1 in an isolated environment. It creates a malicious H2 destination database and triggers Java code execution via a follow-up dataset query, confirming the bug on the vulnerable build and its absence on v1.61.2.
11 · References

References for CVE-2026-59826

Authoritative sources for CVE-2026-59826 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.