fix(mcp): exact-match dangerous flags, stop -c substring false positives#1115
fix(mcp): exact-match dangerous flags, stop -c substring false positives#1115nguyennguyenit wants to merge 1 commit into
Conversation
Previously ValidateArgs flagged any arg containing '-c', '-e', or '-r' as
substrings, blocking legitimate npm package names like 'clickup-cli'. Split
the check: short/long flags now require exact match (or '--flag=value' prefix),
while inline-code patterns ('exec(', '__import__', 'subprocess', etc.) keep
substring semantics.
Closes #1027.
|
Backlog review: merge-candidate. This cleanly fixes #1027 by separating exact dangerous flags from true code-execution substrings, includes regression tests for clickup-cli-style false positives and --flag=value rejection, and go/web checks pass. I closed #1152 as superseded by this cleaner dev-targeted PR. |
clark-cant
left a comment
There was a problem hiding this comment.
PR Review
Verdict: REQUEST CHANGES
Summary
This PR fixes the real false positive from #1027: package names like @nick.bester/clickup-cli should not be rejected just because they contain -c as a substring.
Risk level: medium, because this is security validation for MCP stdio command arguments.
Findings
- [HIGH] internal/mcp/validation.go:103 — short dangerous flags can be bypassed when the option argument is attached to the flag.
The new logic only rejects short flags by exact argument match or flag= form. That fixes the substring false positive, but it also allows forms that many runtimes accept as code-execution flags with attached operands, for example:
- python -cpass / python -c print style attached -c code
- node -e throw style attached -e code
- node -rmodule style attached require preload
Some payloads with parentheses will still be caught later by shellMetaChars, but not all valid code requires those characters. For example, an arg like -cpass has no shell metacharacters and currently passes validation.
Suggested fix: keep the PRs important substring fix, but treat short dangerous options as flags when they appear at the start of an argument too, not anywhere inside it. For example:
- reject exact -c, -e, -r
- reject attached forms beginning with -c, -e, -r when they are intended as short option operands
- continue allowing package names or paths where -c, -e, -r appear later in the string, e.g. @nick.bester/clickup-cli
Please add regression tests for attached short-option bypasses, e.g. -cpass, -ethrow, and -rmodule.
Anti-AI-Slop Check
- Intent clear: yes — fixes a concrete false positive and closes #1027.
- Diff scope justified: yes — small and targeted.
- Refactor justified: not applicable.
- Author explanation needed: no.
Tests / CI
- CI: go ✅, web ✅
- Local targeted check: go test ./internal/mcp -run ValidateArgs ✅
- Test gap: missing negative tests for attached short dangerous flags: -c code, -e code, -r module.
Final Notes
Direction is good, but this validator protects MCP stdio execution. Avoiding substring false positives is right; allowing attached short code-execution flags is too risky to merge as-is.
Summary
Closes #1027.
Test plan