VYPR
Moderate severityNVD Advisory· Published Sep 14, 2024· Updated Sep 16, 2024

h2oai h2o-3 JDBC Connection 1 getConnectionSafe deserialization

CVE-2024-8862

Description

A critical deserialization vulnerability in h2o-3's JDBC Connection Handler allows remote unauthenticated code execution via crafted queries to the /dtale/chart-data/1 endpoint.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A critical deserialization vulnerability in h2o-3's JDBC Connection Handler allows remote unauthenticated code execution via crafted queries to the /dtale/chart-data/1 endpoint.

Vulnerability

Analysis

CVE-2024-8862 is a critical deserialization vulnerability in the getConnectionSafe function within the JDBC Connection Handler component of h2oai h2o-3 version 3.46.0.4. The vulnerability is triggered when processing requests to the /dtale/chart-data/1 endpoint. By manipulating the query argument, an attacker can induce deserialization of untrusted data, a classic vector for arbitrary code execution [1][2].

Attack

Vector

The attack is remotely exploitable without authentication, as the vulnerable endpoint does not enforce access controls. The D-Tale visualizer component, which is bundled with h2o-3, exposes chart-data functionality that accepts user-supplied SQL-like queries. In the vulnerable code path, the query parameter is passed directly to a deserialization operation without sanitization or type checking, allowing an attacker to inject malicious serialized objects [3].

Impact

Successful exploitation leads to remote code execution with the privileges of the h2o-3 process. An attacker can fully compromise the server's confidentiality, integrity, and availability—gaining the ability to execute arbitrary commands, exfiltrate data, or pivot to internal networks [1][2]. The public disclosure of exploit details increases the immediate risk of active exploitation.

Mitigation

The vendor, h2oai, was contacted but did not respond, so no official patch is available. However, a commit in the upstream D-Tale repository introduces a check (enable_custom_filters) that can disable custom queries, which may serve as a workaround [3]. Users should restrict network access to the /dtale/chart-data/1 endpoint, apply input validation, or migrate to a patched version of D-Tale if available. Until a fix is confirmed, this vulnerability should be treated as actively exploitable.

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
dtalePyPI
< 3.14.13.14.1

Affected products

2

Patches

1
b6e309693905

Added check for custom filtering before using custom queries in charts

https://github.com/man-group/dtaleAndrew Schonfeld (Boston)Sep 9, 2024via ghsa
3 files changed · +30 21
  • dtale/dash_application/layout/layout.py+24 20 modified
    @@ -1709,27 +1709,31 @@ def show_map_style(show):
                 ),
                 className="row pt-3 pb-3 charts-filters",
             ),
    -        html.Div(
    +        (
                 html.Div(
    -                [
    -                    html.Div(
    -                        [
    -                            query_label,
    -                            dcc.Input(
    -                                id="query-input",
    -                                type="text",
    -                                placeholder=query_placeholder,
    -                                className="form-control",
    -                                value=query_value,
    -                                style={"lineHeight": "inherit"},
    -                            ),
    -                        ],
    -                        className="input-group mr-3",
    -                    )
    -                ],
    -                className="col",
    -            ),
    -            className="row pt-3 pb-3 charts-filters",
    +                html.Div(
    +                    [
    +                        html.Div(
    +                            [
    +                                query_label,
    +                                dcc.Input(
    +                                    id="query-input",
    +                                    type="text",
    +                                    placeholder=query_placeholder,
    +                                    className="form-control",
    +                                    value=query_value,
    +                                    style={"lineHeight": "inherit"},
    +                                ),
    +                            ],
    +                            className="input-group mr-3",
    +                        )
    +                    ],
    +                    className="col",
    +                ),
    +                className="row pt-3 pb-3 charts-filters",
    +            )
    +            if global_state.load_flag(inputs["data_id"], "enable_custom_filters", False)
    +            else None
             ),
             html.Div(
                 html.Div(
    
  • dtale/views.py+4 1 modified
    @@ -3380,9 +3380,12 @@ def get_chart_data(data_id):
             max: maxY,
         } or {error: 'Exception message', traceback: 'Exception stacktrace'}
         """
    +    custom_query = None
    +    if global_state.load_flag(data_id, "enable_custom_filters", False):
    +        custom_query = get_str_arg(request, "query")
         data = run_query(
             handle_predefined(data_id),
    -        build_query(data_id, get_str_arg(request, "query")),
    +        build_query(data_id, custom_query),
             global_state.get_context_variables(data_id),
         )
         x = get_str_arg(request, "x")
    
  • tests/dtale/test_views.py+2 0 modified
    @@ -1975,6 +1975,7 @@ def test_get_chart_data(unittest, rolling_data):
     
         with app.test_client() as c:
             build_data_inst({c.port: test_data})
    +        global_state.set_app_settings(dict(enable_custom_filters=True))
             response = c.get(
                 "/dtale/chart-data/{}".format(c.port),
                 query_string=dict(query="missing_col == 'blah'"),
    @@ -1997,6 +1998,7 @@ def test_get_chart_data(unittest, rolling_data):
                 response_data["error"],
                 'query "security_id == 51" found no data, please alter',
             )
    +    global_state.set_app_settings(dict(enable_custom_filters=False))
     
         df = pd.DataFrame([dict(a=i, b=np.nan) for i in range(100)])
         df, _ = views.format_data(df)
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.