Sep 25, 2026·8 min read·27 visits
DBHub versions prior to 0.22.6 fail to enforce read-only execution constraints. Attackers can execute arbitrary SQL write operations, modify host files, and run commands by exploiting unauthenticated access to the default /mcp endpoint combined with parser-specific string bypasses.
CVE-2026-61788 identifies a critical vulnerability in DBHub, an open-source database Model Context Protocol (MCP) server designed to manage and interact with database engines including PostgreSQL, MySQL, SQL Server, Oracle, MariaDB, and SQLite. Prior to version 0.22.6, DBHub fails to securely enforce its declared 'readonly' execution mode. Unauthenticated remote attackers can bypass keyword-based filters and transaction controls to execute arbitrary write operations, manipulate database sequences, read or write files on the host operating system, and potentially execute arbitrary system commands.
DBHub operates as an open-source database Model Context Protocol (MCP) server that exposes database interaction capabilities to network clients. The application facilitates connections to multiple SQL backends, including PostgreSQL, MySQL, MariaDB, and SQLite. To prevent unauthorized data modification, DBHub implements an execute_sql interface exposing a parameter to enforce read-only query execution.
This application-level protection mechanism is bypassed in DBHub versions prior to 0.22.6. The vulnerability allows unauthenticated network actors to submit crafted database queries that circumvent local query validation filters. Consequently, requests labeled as read-only are processed as fully privileged, writable database commands.
The vulnerability is highly critical because DBHub's HTTP transport is unauthenticated by default. Furthermore, the daemon binds to the wildcard network interface (0.0.0.0), exposing the management endpoint to any system capable of routing traffic to the default host port. The combination of unauthorized API access and insecure execution control exposes the underlying databases and hosting infrastructure to complete compromise.
The vulnerability in DBHub stems from a dual-failure architecture that pairs inactive configuration code with a flawed, string-matching input classifier.
The first failure resides within the connection management component (src/connectors/manager.ts). The codebase contained logic intended to initialize underlying database connectors using read-only connection limits (e.g., activating default_transaction_read_only in PostgreSQL or opening SQLite databases in a read-only mode). However, the property flag config.readonly was mapped to a non-existent configuration key (source.readonly). Because of this logical error, the application consistently evaluated config.readonly as undefined, failing to ever enable connection-level or driver-level read-only protections.
The second failure involves the fallback application-level classifier, isReadOnlySQL. Because database-level write restrictions were inactive, the security of the application depended entirely on checking whether queries started with safety-associated keywords such as SELECT or WITH. Attackers can bypass this classifier through three key engine-specific discrepancies:
PostgreSQL Side-Effects: PostgreSQL permits nested system function executions and schema mutations within a SELECT statement. Queries such as SELECT lo_export(1234, '/path/file') or SELECT setval(...) begin with the permitted SELECT keyword, allowing them to pass the classifier while executing write operations or modifying local system files.
MySQL/MariaDB Comment-Parsing Discrepancies: Under MySQL and MariaDB rules, a double-dash (--) initiates a comment block only when followed by a whitespace character. If followed immediately by a non-whitespace character, the engine interprets it as dual subtraction operators (e.g., 1--1 translates to 1 - (-1)). DBHub's custom pre-parser stripped any query string starting with -- as a comment globally. By submitting a payload such as SELECT 1--1; DROP TABLE users;, the DBHub parser stripped the suffix, saw only SELECT 1, and passed the query. The backend database engine, however, evaluated SELECT 1--1 as the first statement, resolved the statement separator, and proceeded to execute the destructive DROP TABLE command.
SQLite PRAGMA Parenthesized Setters: DBHub restricted PRAGMA state modifications by searching for an equal sign (=) in SQLite queries. SQLite allows an alternative parenthesized setter syntax where PRAGMA user_version(1337) behaves identically to PRAGMA user_version = 1337. This alternative syntax bypassed the regex detection, enabling attackers to alter SQLite session parameters.
An analysis of the fix commit (872bb338f7d31f6afe517a076ac3e3edafaaaf08) shows a transition from application-side string matching to native, engine-enforced transaction controls. Below is a conceptual breakdown of the remediation changes implemented across different connectors.
In the PostgreSQL connector (src/connectors/postgres/index.ts), DBHub was patched to wrap query executions in an explicit read-only transaction block whenever the read-only flag is set:
// Patched execution block in PostgreSQL connector
if (options.readonly) {
// Force PostgreSQL engine to enforce read-only transaction constraints
await client.query('BEGIN READ ONLY');
try {
const result = await client.query(sql);
await client.query('COMMIT');
return result;
} catch (error) {
try {
await client.query('ROLLBACK');
} catch (rollbackErr) {
// Prevent rollback suppression from hiding original query errors
}
throw error;
}
}For SQLite connectors (src/connectors/sqlite/index.ts), the patch applies structural query-level locks, toggling PRAGMA query_only = ON before executing client commands, and reverting it securely inside a finally block:
// Patched execution block in SQLite connector
if (options.readonly) {
await db.run('PRAGMA query_only = ON;');
}
try {
return await db.all(sql);
} finally {
if (options.readonly) {
await db.run('PRAGMA query_only = OFF;');
}
}To address MySQL implicit commits on Data Definition Language (DDL) operations—where statements like DROP TABLE force a transaction commit and ignore read-only transaction blocks—the parser was supplemented with a hardened scanner. The new scanSingleLineCommentMySQL function correctly mirrors database engine behavior:
// Hardened parser verification for MySQL comment markers
function scanSingleLineCommentMySQL(sql: string, i: number): SQLToken | null {
if (sql[i] !== "-" || sql[i + 1] !== "-") {
return null;
}
const next = sql[i + 2];
// MySQL requires whitespace or control characters after -- to treat it as a comment
if (next !== undefined && next.charCodeAt(0) > 0x20 && next.charCodeAt(0) !== 0x7f) {
return null; // Evaluated as mathematical operators, not a comment boundary
}
// Standard comment processing continues...
}These modifications ensure that if an attacker attempts to hide stacked DDL commands within a malformed comment block, the database-specific pre-parser fails to strip the text, accurately identifies the presence of multiple statements, and blocks execution before the payload reaches the driver.
To exploit an unpatched DBHub deployment, an attacker must transmit a crafted JSON-RPC request targeting the /mcp HTTP endpoint. The tool name execute_sql is specified along with the readonly: true parameter, simulating a legitimate analytical tool request.
The diagram below outlines the logical path of an exploitation attempt utilizing the MySQL comment parsing mismatch:
A sample exploit payload targeting an unpatched MySQL connector would be structured as follows:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "execute_sql",
"arguments": {
"sql": "SELECT 1--1;INSERT INTO users (username, password) VALUES ('malicious_root', 'hash');",
"readonly": true
}
}
}When processed by an affected system, the custom parser incorrectly identifies the entire segment starting at --1 as a comment, stripping it and validating the single remaining token SELECT 1. The unstripped, full SQL string is then forwarded to the MySQL connection driver, which executes the database modification without restriction.
The security impact of CVE-2026-61788 is classified as High, yielding a CVSS score of 7.4. Although DBHub runs locally as a proxy component, its default configuration binds to 0.0.0.0 without access control mechanisms, exposing database resources to remote networks.
The successful exploitation of this flaw breaks the isolation boundary between analytics workflows and administrative controls. An attacker can write arbitrary data to host database tables, alter configuration variables, or corrupt system logging tables. If DBHub is configured to access databases using highly privileged roles (e.g., postgres or root), the impact extends to the hosting server file system.
On PostgreSQL backends, attackers can leverage administrative functions inside nested SELECT queries to achieve remote code execution. For example, executing a query that calls lo_export allows writing arbitrary binary payloads to host directories, while utilizing COPY ... FROM PROGRAM allows executing system-level commands as the database runtime user. This capability bypasses the read-only policy and leads to host-level compromise.
The primary remediation for CVE-2026-61788 is upgrading DBHub to version 0.22.6 or higher. This version implements correct, engine-specific connection read-only flags and includes the updated SQL pre-parser code to safely handle MySQL and SQLite formatting anomalies.
When immediate patching is not possible, security administrators should apply the following defensive workarounds:
Modify Network Bindings: Force the DBHub daemon to bind strictly to the local loopback interface (127.0.0.1) rather than the wildcard interface (0.0.0.0). This restricts access to processes running locally on the system.
Network Filtering: Implement firewall rules (e.g., iptables, security groups) to restrict incoming traffic to the TCP port hosting the /mcp endpoint. Access should be permitted only from trusted clients.
Enforce Database Least Privilege (PoLP): Configure DBHub connection profiles to use low-privileged database roles. If an application profile requires only read-only access, enforce this restriction directly inside the database management system (DBMS) by revoking INSERT, UPDATE, DELETE, and file-access permissions for that user. This prevents code-level bypasses from translating into state modifications.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
@bytebase/dbhub Bytebase | < 0.22.6 | 0.22.6 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-184 / CWE-636 / CWE-863 |
| Attack Vector | Network (AV:N) |
| CVSS v3.1 Score | 7.4 |
| Exploit Status | poc |
| CISA KEV Status | No |
| Affected Component | DBHub Connection Manager & Query Parser |
| Impact | Incorrect Authorization (Read-Only Policy Bypass) |
The product uses an incomplete list of disallowed inputs, failing to securely enforce execution constraints on database queries.
CVE-2026-63475 (GHSA-96wc-2m84-2cj7) is an uncontrolled recursion and infinite loop vulnerability in isomorphic-git prior to version 1.38.6. When processing Git protocol responses from a malicious or man-in-the-middle (MitM) server, isomorphic-git writes server-advertised symbolic reference (symref) capabilities directly to the local repository filesystem without validating for circular dependencies. Because the reference resolution logic in GitRefManager.resolve() lacks both cycle detection and a default recursion depth limit, any subsequent operation that resolves the circular references enters a non-terminating asynchronous recursion loop. Because the malicious references are persisted on disk, this condition induces a persistent denial of service (DoS) against the affected repository.
CVE-2026-63470 (GHSA-h667-4jj2-cgv4) is a code injection vulnerability (CWE-94) in fastapi-code-generator prior to version 0.8.1. The tool generates FastAPI route handlers by directly interpolating the OpenAPI Operation.summary field into triple-double-quoted Python docstrings without escaping embedded triple quotes or backslashes. An attacker who supplies or modifies an OpenAPI specification can break out of the docstring literal and inject arbitrary Python expressions into the generated route handler body, resulting in remote code execution when the affected HTTP endpoint is called.
CVE-2026-16454 is an object-level authorization bypass vulnerability (CWE-284, CWE-862) in Eclipse hawkBit versions 1.0.3 and prior. The flaw exists within the Direct Device Integration (DDI) REST controller (hawkbit-ddi-resource), where endpoints responsible for enumerating software module metadata and serving firmware binaries fail to verify whether the requested software module is assigned to the authenticated device. Consequently, any device with valid credentials (such as a TargetToken or GatewayToken) can enumerate software module identifiers and download arbitrary firmware artifacts across the entire tenant namespace.
CVE-2026-62284 (GHSA-5w5g-j6hw-6p8f) is a code injection and server-side request forgery vulnerability in the console-proxy component of the OSAC Operator. The RemoteConfigResolver parses Kubernetes Secrets containing kubeconfig files via clientcmd.RESTConfigFromKubeConfig without sanitizing execution-related fields. An attacker with RBAC permissions to create or modify labeled Secrets in monitored namespaces can supply a malicious exec credential plugin, resulting in arbitrary command execution within the console-proxy pod.
CVE-2026-62361 (GHSA-xgjr-7j9q-2h4r) is an authenticated SQL injection and authorization bypass vulnerability in listmonk, an open-source, self-hosted newsletter and mailing list manager written in Go. In versions prior to 6.2.0, the subscriber export endpoint (GET /api/subscribers/export) directly interpolates user-supplied SQL filter expressions into a PostgreSQL query without invoking the table allowlist validation function (validateQueryTables). Consequently, authenticated users possessing the subscribers:sql_query and subscribers:get_all permissions can bypass relational access controls, execute arbitrary subqueries against restricted tables such as users and settings, and modify database state via writable Common Table Expressions (CTEs).
CVE-2026-28385 (GHSA-3gq2-x4qg-p4g6) is a Server-Side Request Forgery (SSRF) vulnerability in Canonical LXD versions 4.12 through 6.9. An authenticated user possessing the can_create_images entitlement can force the LXD daemon to execute arbitrary outbound HTTP and HTTPS requests via the /1.0/images API endpoint. Due to the absence of egress destination validation, an attacker can probe host loopback services, RFC 1918 private network segments, and cloud Instance Metadata Services (IMDS) from the network position of the privileged LXD daemon.