~ 3 min read

The Tale of the Vulnerable MCP Database Server

share on
The MCP Database Server by ExecuteAutomation had a critical vulnerability that allowed SQL injection attacks, bypassing its "read-only" mode. This article explores the flaw, its exploitation, and mitigation strategies.

In the world of software development, security is paramount. This story unfolds around the MCP Database Server, a tool designed to facilitate agentic workflows with various database servers, including PostgreSQL. However, a critical vulnerability was discovered, allowing attackers to bypass the “read-only” mode, leading to potential denial of service and unauthorized data access.

This article brings the tale of a vulnerability, its exploitation, and the necessary steps to mitigate such risks.

Background & Prior Art

The MCP Database Server, developed by ExecuteAutomation, is a tool that provides an interface for interacting with different database servers. It is distributed via the npm package @executeautomation/database-server and is publicly available on the npm registry.

The server is designed to operate in a “read-only” mode, allowing only data retrieval operations. However, a flaw in its security controls has been identified, exposing it to potential abuse.

The Vulnerability

The vulnerability, assigned CVE-2025-59333, stems from improper access control in the server’s code. The server attempts to enforce a “read-only” mode by checking if a query string starts with SELECT. This naive approach fails to account for the complexities of SQL queries and the capabilities of database servers like PostgreSQL.

// Handle tool calls
server.setRequestHandler(CallToolRequestSchema, async (request) => {
switch (request.params.name) {
case "read_query": {
const query = request.params.arguments?.query as string;
if (!query.trim().toLowerCase().startsWith("select")) {
throw new Error("Only SELECT queries are allowed with read_query");
}
try {
const result = await dbAll(query);
return {
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
isError: false,
};
} catch (error: any) {
throw new Error(`SQL Error: ${error.message}`);
}
}
}
});

How It Works

The server’s security mechanism relies on the assumption that queries starting with SELECT are inherently safe. However, this is not the case. PostgreSQL, for instance, allows for complex operations within a SELECT query, including calling stored procedures and executing administrative commands.

Exploitation

An attacker can exploit this vulnerability by crafting a SELECT query that performs unintended operations. For example, a query like SELECT some_function_that_updates_data(); can execute a stored procedure that modifies data. Similarly, SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE ...; can terminate active database connections, leading to a denial of service.

Reproduction Steps

  1. Simulate a long-running query: SELECT pg_sleep(5 * 60);
  2. Retrieve the process ID (PID) of the query: SELECT pid, usename, state, query FROM pg_stat_activity;
  3. Terminate the query using its PID: SELECT pg_terminate_backend(PID);

These steps demonstrate how an attacker can disrupt database operations using the MCP interface.

Impact

The vulnerability poses significant security risks, including:

  • Denial of Service (DoS): By terminating active queries, an attacker can disrupt the availability of the database server.
  • Unauthorized Data Access: The ability to execute arbitrary queries can lead to data leaks and unauthorized access to sensitive information.

Recommendations

To mitigate these risks, the following measures are recommended:

  • Avoid relying solely on “starts with” checks for query validation.
  • Implement strict access controls, limiting users to specific tables and operations.
  • Prevent the execution of multiple SQL queries in a single request.
  • Enforce fine-grained permissions on the database server, ensuring users have explicit access to only the necessary capabilities.

CVE Details

  • CWE: CWE-284: Improper Access Control
  • CVSS Score: 8.1 (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:H)

References

  1. GitHub Kanban MCP Server Vulnerability
  2. iOS Simulator MCP Server Vulnerability
  3. Node.js Secure Coding
  4. Bypassing Access Control in PostgreSQL
  5. Cursor MCP Server Vulnerability

Conclusion

The story of the MCP Database Server serves as a cautionary tale about the importance of robust security controls. By understanding the vulnerabilities and implementing the recommended measures, developers can protect their systems from similar threats. For more insights and security research, follow Liran Tal on Twitter and explore his work on GitHub.


Node.js Security Newsletter

Subscribe to get everything in and around the Node.js security ecosystem, direct to your inbox.

    JavaScript & web security insights, latest security vulnerabilities, hands-on secure code insights, npm ecosystem incidents, Node.js runtime feature updates, Bun and Deno runtime updates, secure coding best practices, malware, malicious packages, and more.