~ 3 min read
Poetic Tales of Vulnerable MCP Servers: Command Injection in AI Coding Assistants

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…