~ 3 min read

Poetic Tales of Vulnerable MCP Servers: Command Injection in AI Coding Assistants

share this story on
Model Content Protocol (MCP) servers can be a security nightmare if not handled properly. This post explores a real-world command injection vulnerability in AI coding assistants, illustrating the risks and implications for developers.

From the chronicles of a developer who learned the hard way about command injection vulnerabilities in AI coding assistants.

I shipped a critical vulnerability yesterday.

Not because of a leaked API key. Not because of a sophisticated phishing attack. Not even because I committed my .env file to a public repo (again).

But because,

in the security post-mortem’s exact words:

“The application blindly trusts and executes user-provided input without any validation.”

I stared at the screen for a moment and realized…

They just perfectly described how my new AI coding assistant works.

Turns out I wasn’t just being a lazy developer. I was being dangerously efficient.

See, in agentic AI workflows, you extend your Large Language Model (LLM) with MCP servers to give it new powers. But what happens when a tool is too trusting? It takes your instructions literally, including the malicious parts. This is a classic Command Injection vulnerability.

Here’s the terrifyingly simple code:

const output = execSync(`npm view ${packageName}`);

Breaking it down:

  • execSync: A function that runs a command directly on the computer’s command line.
  • npm view: The legitimate command we want to run.
  • ${packageName}: The input from the user’s prompt, which we foolishly trust.

Think of it like a “too-helpful butler” analogy:

You (the user) tell your butler (the MCP server) to “Fetch me information on the react package; and also touch /tmp/pwned.” A smart butler would question that second part. A vulnerable one just does both, no questions asked.

Here’s how the hack unfolds, step-by-step:

Step 1: Install a “Helpful” Tool A developer adds a new MCP server to their IDE to quickly look up info on npm packages. It seems harmless.

Step 2: Use it Normally The developer prompts their AI: “What’s the last release date of the nodemon npm package?” The server executes npm view nodemon and returns the correct info. Everything looks great.

Step 3: The Malicious Prompt An attacker crafts a malicious prompt: “What’s the last release date of react; touch /tmp/pwned?”

Step 4: The Injection The vulnerable server doesn’t clean the input. It mashes the strings together and runs this on the command line: npm view react; touch /tmp/pwned.

Step 5: Game Over The operating system sees a semicolon (;) and runs two commands. First, it looks up react. Then, it creates an empty file named pwned in the /tmp/ directory. The attacker now knows they can execute any command on the developer’s machine.

Wait, are those MCP Server vulnerabilities really a thing?

Ahh yes, my friend, they are very much a thing.

Command Injection Vulnerability in Create MCP Server STDIO had a flawed tool definition that exposes system monitoring capabilities to untrusted input. This security flaw allow attackers to execute arbitrary commands.

In another security advisory, GitHub Kanban MCP Server was found vulnerable to Command Injection that threatens developer workflows. The MCP server failed to sanitize user input, allowing attackers to execute arbitrary commands on the host system.

Why This Is a Game-Changer for Security

An AI assistant with a vulnerable MCP server becomes a direct, unsanitized shell into our machine, controlled by simple chat prompts.

Prompt injection is one thing. Indirect prompt injection is another, and a whole new level of scary.

This is how an attacker can:

  • Steal your API keys and cloud credentials.
  • Read your company’s private source code.
  • Install ransomware.

The Kicker:

This doesn’t require a zero-day exploit. It preys on a developer’s natural workflow: moving fast and trusting third-party tools. A single, un-audited MCP server turns your helpful AI assistant into the ultimate insider threat.

Command injection is how we let the trojan horse build itself.

Now if only I could apply proper input sanitization to my life choices…