← All rules
mcp-scan rule
Shell injection risk
shell-injection-riskcriticalWhat mcp-scan saw
The config scanner walked each string argument and split it three ways: $(...) or backtick pairs are command substitution and push CRITICAL; a ${...} expression that is not exactly ${NAME} pushes MEDIUM; a plain ${NAME} in any case is allowed and pushes nothing.
Why it fires
Nothing in an MCP args array is shell-expanded. The client hands the array to the process directly, so $(whoami) stays four literal words unless something downstream re-shells it. That means command substitution in a config is either dead text or a payload aimed at a wrapper that does re-shell, and the second case is why it is CRITICAL rather than a style note.
When this is a false positive
- The backtick shape is /`.*`/ on the whole argument, so any argument carrying two backticks matches. A --system-prompt or --instructions argument with a markdown code span fires CRITICAL with no substitution present.
- Some launchers and shell wrappers do expand these before handing off, which makes $(...) intentional. It is still a live injection point, so this is a case to document rather than dismiss.
- The MEDIUM variant fires on ${BASE}/api, which is a normal way to compose a URL from a prefix. It is a config smell only because the client will not expand it, so the server receives the literal braces.
How to fix it
- Read the argument quoted in the finding text and decide which of the two shapes it is.
- For the CRITICAL shape, delete the substitution. If you need a computed value, compute it before launch and pass the result as a literal or through env.
- For the MEDIUM shape, replace ${BASE}/api with a fully resolved literal, or split it into two arguments where the variable stands alone as ${BASE}.
- If the backticks are prose in a prompt argument, replace them with quotes so the argument stops matching.
- If a wrapper genuinely expands your arguments, remove the wrapper. Passing untrusted config text through a shell is the underlying problem the rule is pointing at.