VYPR
Critical severityNVD Advisory· Published Sep 6, 2024· Updated Sep 6, 2024

CVE-2024-45758

CVE-2024-45758

Description

H2O.ai H2O through 3.46.0.4 allows attackers to arbitrarily set the JDBC URL, leading to deserialization attacks, file reads, and command execution. Exploitation can occur when an attacker has access to post to the ImportSQLTable URI with a JSON document containing a connection_url property with any typical JDBC Connection URL attack payload such as one that uses queryInterceptors.

AI Insight

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

CVE-2024-45758 allows attackers to craft arbitrary JDBC URLs via the ImportSQLTable endpoint, enabling deserialization, file reads, and remote code execution in H2O-3 up to 3.46.0.4.

Vulnerability

Overview

CVE-2024-45758 affects H2O.ai H2O-3 versions up to and including 3.46.0.4. The root cause is insufficient validation of the connection_url parameter accepted by the ImportSQLTable URI endpoint. An attacker can submit a JSON object containing a malicious JDBC URL, bypassing any intended security checks like the getConnectionSafe method, which only wraps the connection without restricting its parameters [1][2][4].

Exploitation

Prerequisites

Exploitation requires network access to the H2O instance and the ability to POST to the ImportSQLTable endpoint. No prior authentication is needed. The vulnerable endpoint accepts a JSON document with a connection_url property. Attackers can embed JDBC URL payloads that leverage features like queryInterceptors (e.g., for MySQL) or autoDeserialize to trigger deserialization of untrusted data, read local files, or execute operating system commands [2][3][4].

Impact

A successful attack can lead to arbitrary file reads, deserialization of malicious objects, and remote code execution on the H2O server. Given that H2O is often deployed in data-science environments with access to sensitive data or internal systems, this vulnerability poses a critical risk to data confidentiality, integrity, and availability [2][4].

Mitigation

H2O-3 has released a commit (f714edd) that adds validation to reject JDBC URLs containing dangerous parameters such as autoDeserialize, allowLoadLocalInfile, and queryInterceptors [3]. Users should update to a patched version (after 3.46.0.4) or apply the provided validation logic. If upgrading is not possible, administrators should restrict network access to the H2O UI and API endpoints, especially the ImportSQLTable URI [1][3].

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
ai.h2o:h2o-coreMaven
<= 3.46.0.7
h2oPyPI
<= 3.46.0.7

Affected products

3

Patches

1
f714edd6b842

GH-16622 Validate parameters also when user define jdbs with key-value (#16624)

https://github.com/h2oai/h2o-3Adam ValentaJun 18, 2025via ghsa
2 files changed · +70 1
  • h2o-core/src/main/java/water/jdbc/SQLManager.java+1 1 modified
    @@ -42,7 +42,7 @@ public class SQLManager {
     
       private static final String DISALLOWED_JDBC_PARAMETERS_PARAM = H2O.OptArgs.SYSTEM_PROP_PREFIX + "sql.jdbc.disallowed.parameters";
     
    -  private static final Pattern JDBC_PARAMETERS_REGEX_PATTERN = Pattern.compile("(?i)[?;&]([a-z]+)=");
    +  private static final Pattern JDBC_PARAMETERS_REGEX_PATTERN = Pattern.compile("(?i)([a-z0-9_]+)\\s*=\\s*");
     
       private static final List<String> DEFAULT_JDBC_DISALLOWED_PARAMETERS = Stream.of(
               "autoDeserialize", "queryInterceptors", "allowLoadLocalInfile", "allowMultiQueries", //mysql 
    
  • h2o-core/src/test/java/water/jdbc/SQLManagerTest.java+69 0 modified
    @@ -165,4 +165,73 @@ public void testValidateJdbcConnectionStringMysql() {
     
         SQLManager.validateJdbcUrl(mysqlMaliciousJdbc);
       }
    +
    +  @Test
    +  public void testValidateJdbcConnectionStringMysqlKeyValuePairs() {
    +    exception.expect(IllegalArgumentException.class);
    +    exception.expectMessage("Potentially dangerous JDBC parameter found: autoDeserialize");
    +
    +    String jdbcConnection = "jdbc:mysql://(host=127.0.0.1,port=3308,autoDeserialize=true,queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor,user=deser_CUSTOM,maxAllowedPacket=655360)";
    +
    +    SQLManager.validateJdbcUrl(jdbcConnection);
    +  }
    +
    +  @Test
    +  public void testValidateJdbcConnectionStringMysqlKeyValuePairsSpace() {
    +    exception.expect(IllegalArgumentException.class);
    +    exception.expectMessage("Potentially dangerous JDBC parameter found: autoDeserialize");
    +
    +    String jdbcConnection = "jdbc:mysql://(host=127.0.0.1,port=3308, autoDeserialize  =  true,queryInterceptors = com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor,user=deser_CUSTOM,maxAllowedPacket=655360)";
    +
    +    SQLManager.validateJdbcUrl(jdbcConnection);
    +  }
    +
    +  @Test
    +  public void testValidateJdbcConnectionStringMysqlKeyValuePairsCAPITAL() {
    +    exception.expect(IllegalArgumentException.class);
    +    exception.expectMessage("Potentially dangerous JDBC parameter found: AUTODeserialize");
    +
    +    String jdbcConnection = "jdbc:mysql://(host=127.0.0.1,port=3308, AUTODeserialize  =  true,queryInterceptors = com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor,user=deser_CUSTOM,maxAllowedPacket=655360)";
    +
    +    SQLManager.validateJdbcUrl(jdbcConnection);
    +  }  
    +
    +  @Test
    +  public void testValidateJdbcConnectionStringMysqlSpaceBetween() {
    +    exception.expect(IllegalArgumentException.class);
    +    exception.expectMessage("Potentially dangerous JDBC parameter found: allowLoadLocalInfile");
    +
    +    String jdbcConnection = "jdbc:mysql://127.0.0.1:3306/mydb?allowLoadLocalInfile  =  true&  autoDeserialize=true";
    +
    +    SQLManager.validateJdbcUrl(jdbcConnection);
    +  }
    +
    +  @Test
    +  public void testValidateJdbcConnectionStringMysqlCAPITAL() {
    +    exception.expect(IllegalArgumentException.class);
    +    exception.expectMessage("Potentially dangerous JDBC parameter found: AUTODESERIALIZE");
    +
    +    String jdbcConnection = "jdbc:mysql://127.0.0.1:3306/mydb?AUTODESERIALIZE  =  true&  allowLoadLocalInfile=true";
    +
    +    SQLManager.validateJdbcUrl(jdbcConnection);
    +  }  
    +
    +  @Test
    +  public void testValidateJdbcConnectionStringMysqlOneParameter() {
    +    exception.expect(IllegalArgumentException.class);
    +    exception.expectMessage("Potentially dangerous JDBC parameter found: allowLoadLocalInfile");
    +
    +    String jdbcConnection = "jdbc:mysql://127.0.0.1:3306/mydb?allowLoadLocalInfile=true";
    +
    +    SQLManager.validateJdbcUrl(jdbcConnection);
    +  }
    +
    +  /**
    +   * Test fail if any exception is thrown therefore no assert
    +   */
    +  @Test
    +  public void testValidateJdbcConnectionStringMysqlPass() {
    +    String jdbcConnection = "jdbc:mysql://127.0.0.1:3306/mydb?allowedParameter=true";
    +    SQLManager.validateJdbcUrl(jdbcConnection);
    +  }
     }
    

Vulnerability mechanics

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

References

8

News mentions

0

No linked articles in our index yet.