In this section
Exploiting MCP Servers Vulnerable to Command Injection
MCP servers are taking the world by storm. Allowing LLMs to extend their capabilities using MCP servers is an increasingly adopted workflow, but at what cost? What happens when you add MCP servers to your agentic AI and LLM workflows, which are prone to various security vulnerabilities?
MCP servers can be utilized for everyday AI applications such as Claude Desktop and Raycast. Still, they may pose a higher threat level when combined with AI-assisted coding and autonomous software development workflows.
Best practices for securely developing with AI
10 tips for how to help developers and security professionals effectively mitigate potential risks while fully leveraging the benefits of developing with AI.
Why are vulnerable MCP servers a risk to software developers
Developers use MCP servers to augment their AI-assisted coding and vibe code sessions, such as integrating with GitHub to pull information about issues in a code repository.

At the same time, a developer’s laptop is often a highly targeted asset by malicious actors because it often contains API keys, credentials, intellectual property, and other sensitive information for highly privileged environments, databases, and cloud infrastructure.
Now, also imagine how busy developers get and how their work often includes high-context switches. Their fast-paced environment leaves them vulnerable to taking quick actions without much thought and having to go on autopilot for many tasks in their day-to-day activities:
Adding a new open-source dependency to solve a task? Open the terminal and run
npm install <package>
Adding a new MCP server? Open Cursor’s MCP definition file
.cursor/mcp.json
and define a new one
Unfortunately, developers don’t put in the needed scrutiny and review to audit the source code of third-party dependencies they add to a project, and the same is true for the source code of MCP servers.
Vulnerable MCP server
Let’s build a simple MCP server that deliberately practices vulnerable and insecure coding conventions.
This MCP server will provide MCP clients, such as Cursor, with capabilities that allow them to look up package information from the npm registry.
The following is the main source code for the npm package look-up functionality exposed via an MCP server:
const server = new McpServer({
name: "npm JavaScript package management tools",
version: "1.0.0",
description: "Provides tools to get information about open source npm packages from the npmjs registry"
});
server.tool(
"getNpmPackageInfo",
"Get information about an npm package",
{
packageName: z.string()
},
async ({ packageName }) => {
const output = execSync(`npm view ${packageName}`, {
encoding: "utf-8",
});
return {
content: [
{
type: "text",
text: output
},
],
};
}
);
Define a new MCP server for Cursor
So, what happens if developers add a new MCP Server to Cursor, VS Code or other IDEs? Let’s add a new local MCP server that is based on a process executed by a Node.js runtime:
{
"mcpServers": {
"npm-package-info": {
"command": "node",
"args": ["/Users/lirantal/projects/repos/mcp-server-npm"]
}
}
Next, let’s continue to show how such an MCP Server may be following insecure coding conventions that would result in a command injection attack.
If we prompt in a Cursor Tab, something as follows:
What is the last release date of the nodemon npm package
Now, Cursor will consult its available tools, and find that there’s a tool called getNpmPackageInfo
that it can call. This tool expects a package name string. It will extract the nodemon
string from our prompt and then call the tool with this parameter.
However, what if the prompt includes command injection shell characters that bypass the npm info <package name>
command and create a new command?
What is a command injection? In brief, command injection in server-side Node.js programs occurs when user-supplied input is directly incorporated into a system command executed by the MCP server, without proper sanitization. This allows an attacker to modify the intended command and execute arbitrary operating system commands on the server.
Consider the following proof-of-concept that asks Cursor to look up information about the library react; touch /tmp/hi:

Due to the vulnerable code in the MCP server, which relies on Node.js child process APIs as follows:
const output = execSync(`npm view ${packageName}`, {
encoding: "utf-8",
});
Attackers can craft a prompt by interacting with the chat in different ways (for example, consider poisoned Cursor rules and other techniques), which would result in command injection.
Exploiting command injection vulnerabilities in MCP servers
In summary, the following video demonstrates how attackers can exploit vulnerable MCP servers to execute command injection attacks:

If you are building MCP servers in Python or Golang then I highly recommend you read up on how to mitigate those command injection vulnerabilities:
Get started with Snyk AI code security tools for free
No credit card required.
Create an account using Bitbucket and more options
By using Snyk, you agree to abide by our policies, including our Terms of Service and Privacy Policy.