
अनपैच्ड MCP STDIO कमांड-इंजेक्शन दोष (CVE-2026-30623 परिवार) के लिए ड्रॉप-इन फिक्स
अनपैच्ड MCP STDIO कमांड-इंजेक्शन दोष के लिए एक ड्रॉप-इन फिक्स (CVE-2026-30623 परिवार, जिसे OX Security ने अप्रैल 2026 में "by design" के रूप में खुलासा किया था — कोई SDK पैच नहीं आ रहा है)। एक लाइन इम्पोर्ट करें, और आपके Python ऐप द्वारा लॉन्च किया जाने वाला हर stdio MCP सर्वर, OS द्वारा प्रोसेस स्पॉन करने से पहले उसके command/args/env को वैध (validated) कर दिया जाएगा।
यदि आप यहाँ नए हैं, तो पहले Scope पढ़ें, फिर Install और Getting started आपको दो मिनट से भी कम समय में सुरक्षित कर देंगे।
Pre-1.0, सक्रिय रूप से विकसित।
check/launch/rules)
लागू हैं और एक स्वचालित परीक्षण सूट द्वारा कवर किए गए हैं जो परीक्षण मशीन पर स्थापित वास्तविक बाइनरी (python, node, npx) के विरुद्ध चलता है --
मॉक्स नहीं -- जिसमें एक वास्तविक स्पॉन किए गए सर्वर फिक्स्चर के माध्यम से एक प्रामाणिक एंड-टू-एंड MCP हैंडशेक, और launch का एक वास्तविक सबप्रोसेस-स्तरीय परीक्षण शामिल है।दायरे में: stdio MCP सर्वर लॉन्च (command + args + env) को OS प्रोसेस-स्पॉन परत तक पहुँचने से पहले वैध करना, विशेष रूप से SECURITY.md में वर्णित कमांड/आर्गुमेंट-इंजेक्शन पथ को बंद करने के लिए।
स्पष्ट रूप से दायरे से बाहर: किसी सर्वर के घोषित टूल्स को जोखिम भरी क्षमताओं के लिए स्कैन करना (वह एक अलग समस्या है -- AgentGuard देखें), स्पॉन किए गए प्रोसेस को सैंडबॉक्स करना, और गैर-stdio (SSE/HTTP) MCP ट्रांसपोर्ट।
git clone <this-repo>
cd mcpshield
pip install -e . # core CLI: click + rich only
pip install -e ".[mcp]" # if you also want the Python autopatch (needs the `mcp` SDK)
Verify it worked:
mcpshield --version
mcpshield --help
यदि आपका ऐप Python में लिखा है और StdioServerParameters बनाता है /
स्वयं mcp.client.stdio.stdio_client को कॉल करता है, तो अपने entrypoint के बिल्कुल ऊपर एक इम्पोर्ट जोड़ें -- इससे पहले कि कोई अन्य चीज़ mcp.client.stdio को इम्पोर्ट करे:
import mcpshield.autopatch # side-effect import; must come first
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
# ... use stdio_client exactly as before -- it's now validated
अब एक असुरक्षित लॉन्च कभी भी प्रोसेस स्पॉन करने के बजाय mcpshield.core.errors.UnsafeConfigurationError
(एक ValueError उपवर्ग) उठाएगा।
बिना कुछ चलाए mcpServers-शैली कॉन्फ़िग फ़ाइल का ऑडिट करें:
mcpshield check claude_desktop_config.json
+---------------------------------------------------------------+
| Server | Status | Command | Detail |
|------------------+---------+---------+------------------------|
| filesystem | OK | npx | - |
| evil-server | BLOCKED | npx | Argument '...' contains|
| | | | shell metacharacter |
+---------------------------------------------------------------+
1 ok, 0 warned, 1 blocked
यदि कुछ भी BLOCKED है तो गैर-शून्य (non-zero) exit कोड देता है (WARN पर भी असफल होने के लिए --strict जोड़ें) -- इसे सीधे CI में डालें।
उस MCP क्लाइंट (Node, Java, Rust, ...) के लिए जो Python autopatch का उपयोग नहीं कर सकता, उसके कॉन्फ़िग को वास्तविक कमांड के बजाय mcpshield की ओर इंगित करें:
{
"command": "mcpshield",
"args": ["launch", "--", "npx", "-y", "some-mcp-server"]
}
launch वैध करता है, फिर वास्तविक कमांड को उसी stdio के साथ निष्पादित करता है जिसकी आपका MCP क्लाइंट अपेक्षा करता है (transparent passthrough) -- या यदि लॉन्च असुरक्षित है तो स्पष्ट त्रुटि के साथ मना कर देता है।
नेटिव बाइनरी को आर्गुमेंट जाँच में ढील दी जाती है क्योंकि वे सीधे exec करते हैं --
आर्गुमेंट सूची को दोबारा पार्स करने के लिए कोई शेल नहीं होता। Shell-interpretable
कमांड (सबसे सामान्यतः Windows पर npx.cmd/npx.bat) के लिए सख्त जाँच होती है
क्योंकि अंतर्निहित CVE ठीक इसी तंत्र का शोषण करता है।
दोनों जानबूझकर, प्रति-मान (per-value) opt-in हैं -- कभी भी कोई blanket "disable checks" फ़्लैग नहीं:
allow_raw_args=["--some-value-with-a-pipe"] (लाइब्रेरी) उन विशिष्ट आर्गुमेंट
मानों को छूट देता है जिनकी आपने समीक्षा की है और जिन पर भरोसा है।allow_env=["SOME_VAR"] सामान्यतः हटाए जाने वाले पर्यावरण चर (environment variable) को बिना संशोधन के गुजरने की अनुमति देता है।git clone आवश्यक है।mcp.client.stdio.stdio_client को पैच करता है जैसा कि पैच समय पर
देखा गया है। जो कोड पहले से अपना स्वयं का संदर्भ रखता है (जैसे
import mcpshield.autopatch से पहले from mcp.client.stdio import stdio_client
निष्पादित करना) उसे बायपास कर देगा -- हमेशा पहले mcpshield.autopatch इम्पोर्ट करें।check उस मशीन का उपयोग करके कमांड हल करता है जिस पर यह चलता है। एक कॉन्फ़िग जो
वास्तव में तैनात की गई मशीन पर अलग ढंग से हल होगा (अलग PATH,
अलग स्थापित टूल्स) वहाँ अलग परिणाम दे सकता है।mcpshield/
autopatch.py # one-line-import fix for Python MCP hosts
core/
validate.py # the validation engine (command/args/env checks)
rules.py # blocklist/allowlist data
errors.py # UnsafeConfigurationError
cli/
main.py
commands/ (check.py, launch.py, rules.py)
tests/
fixtures/ # real benign MCP server + sample/malicious configs
pip install -e ".[dev,mcp]"
pytest
परीक्षण सूट उस मशीन पर स्थापित वास्तविक python/node/npx बाइनरी के विरुद्ध मान्य करता है
जिस पर यह चलता है (उसी तरह हल किया गया जैसे इंजन स्वयं उन्हें हल करता है), और इसमें एक वास्तविक स्पॉन किए गए सर्वर फिक्स्चर के माध्यम से एक प्रामाणिक एंड-टू-एंड MCP हैंडशेक शामिल है -- मॉक्स नहीं।
| Check | Native binary (e.g. python.exe) | Shell-interpretable (.cmd/.bat/shebang script) |
|---|
Shell metacharacters (&, |, ;, backtick, $(...), ...) in an argument | Allowed | Blocked |
| NUL byte / newline in an argument | Blocked | Blocked |
Command resolves via relative path traversal (..) | Blocked | Blocked |
| Command doesn't resolve to a real file | Blocked | Blocked |
LD_PRELOAD / NODE_OPTIONS / etc. in env | Stripped (warning) | Stripped (warning) |
PYTHONPATH in env | Flagged (warning), not stripped | Flagged (warning), not stripped |
| Command | What it does |
|---|
mcpshield check <config> [--format table|json] [--strict] | Static audit of an mcpServers config. Never executes anything. Non-zero exit on any BLOCKED (or WARN too, with --strict). |
mcpshield launch -- <command> [args...] | Validates, then executes the real command with passthrough stdio. |
mcpshield rules list | Shows the active shell-metacharacter blocklist, environment-variable lists, and known safe launcher binaries. |