medium
MCP server launched through a shell
The command is bash, sh, cmd, powershell or similar, with the real server started from a shell string.
Why it matters
A shell makes it easy for arguments or environment values to run extra commands, and hides what actually executes.
How to fix it
Call the server's executable directly with an argument list.
Before
{
"mcpServers": {
"db": {
"command": "bash",
"args": [
"-c",
"cd ~/db && node server.js"
]
}
}
}After
{
"mcpServers": {
"db": {
"command": "node",
"args": [
"/home/alex/db/server.js"
]
}
}
}Illustrative configs. The checker flags the “before” version with this finding and not the “after” version.
Other checks
- Secret written into an MCP config
- Secret passed as a command-line argument
- Secret inside an MCP server URL
- Remote MCP server over unencrypted http
- Remote MCP server with no credentials configured
- Unpinned MCP server package or image
- MCP server installs without asking (npx -y)
- MCP server container runs --privileged
- MCP server container shares the host network
- Broad host folder or Docker socket mounted into an MCP container
- MCP filesystem server with access to a very broad path
- MCP server that can run shell commands
- MCP tools auto-approved or always allowed