MCP stdio सर्वरों के लिए गहन सुरक्षा बंडल: ड्रॉप-इन guardExec/guardSpawn रैपर, AST ऑडिट CLI, संदर्भ MCP सर्वर। Ox-Security 200k-server stdio-RCE श्रेणी (LiteLLM CVE-2025-69256) को समाप्त करता है। MIT, TypeScript, Node >= 20।
<!-- studiomeyer-mcp-stack-banner:start -->
> **[StudioMeyer MCP Stack](https://studiomeyer.io)** का हिस्सा — Mallorca 🌴 में निर्मित · ⭐ अगर आप इसका उपयोग करते हैं
<!-- studiomeyer-mcp-stack-banner:end -->
# mcp-stdio-shellguard
<!-- badges -->
[](https://www.npmjs.com/package/mcp-stdio-shellguard)
[](https://www.npmjs.com/package/mcp-stdio-shellguard)



<!-- /badges -->MCP stdio सर्वर के लिए defense-in-depth बंडल। `child_process.exec/spawn` को allowlist + sandbox + replay-detection के साथ रैप करता है, साथ ही एक AST ऑडिट CLI (`mcp-shellguard-audit`) प्रदान करता है जो MCP सर्वर स्रोतों में असैनिटाइज़्ड शेल कॉल्स को स्कैन करता है। यह Ox-Security MCP stdio-RCE श्रेणी (200k कमज़ोर सर्वर, मई 2026 प्रकटीकरण) को बंद करता है।
- **MCP spec**: 2025-06-18
- **SDK**: `@modelcontextprotocol/sdk` ^1.29.0
- **Node**: >= 20
- **License**: MIT
- **Author**: Matthias Meyer (StudioMeyer)
## Install
```bash
npm install mcp-stdio-shellguard
```
या सीधे इंस्टॉल किए बिना ऑडिट CLI चलाएँ:
```bash
npx -y -p mcp-stdio-shellguard mcp-shellguard-audit scan ./src
```
## यह आपको क्या देता है
तीन परतें, चरणबद्ध रूप से opt-in:
1. **लाइब्रेरी API** — drop-in `guardExec` / `guardSpawn` जिन्हें आप अपने
स्वयं के MCP सर्वर से कॉल करते हैं। डिफ़ॉल्ट-अस्वीकार allowlist, सैंडबॉक्स प्रोफ़ाइल, रीप्ले विंडो।
2. **ऑडिट CLI** — `mcp-shellguard-audit scan <path>` AST को ट्रैवर्स करता है, 12
एंटी-पैटर्न की रिपोर्ट करता है, LOW (`no timeout`) से लेकर CRITICAL (`exec(\`...${userInput}...\`)`) तक।
3. **संदर्भ MCP सर्वर** — `mcp-stdio-shellguard-demo` 8 टूल्स को उजागर करता है
ताकि MCP Inspector / Claude Desktop बंडल को सीधे चला सकें।
## टूल्स (संदर्भ सर्वर)
| टूल | प्रकार | उद्देश्य |
|------|------|---------|
| `guard_exec` | विनाशकारी | सुरक्षित `child_process.exec`। args[] वेक्टर, allowlist + सैंडबॉक्स + रीप्ले को बाध्य करता है। `stdout`, `stderr`, `exitCode`, `canonicalHash`, `isReplay`, `trustTier` लौटाता है। |
| `guard_spawn` | विनाशकारी | सुरक्षित `child_process.spawn`। पूर्ण बॉडी के बजाय stdout/stderr के SHA-256 हैश लौटाता है। `shell:true` को सख्ती से अस्वीकार करता है। |
| `register_allowlist` | परिवर्तनकारी | एक टूल नाम को executable + args regex के साथ पंजीकृत करें। पंजीकरण के बिना डिफ़ॉल्ट-अस्वीकार लागू होता है। |
| `audit_source` | केवल-पठन | शेल-इंजेक्शन एंटी-पैटर्न के लिए TS/JS पथ को स्कैन करें। `AuditFinding[]` + सारांश लौटाता है। |
| `audit_report` | केवल-पठन | ऑडिट परिणाम को markdown / json / SARIF 2.1.0 के रूप में फ़ॉर्मेट करें। |
| `replay_check` | केवल-पठन | किसी इनवोकेशन के लिए कैनोनिकल SHA-256 हैश की गणना करें और रिपोर्ट करें कि यह पहले से रीप्ले विंडो में है या नहीं। |
| `sandbox_status` | केवल-पठन | सक्रिय सैंडबॉक्स प्रोफ़ाइल + ठोस सीमाएँ + cgroup-v2 सक्रिय फ़्लैग की रिपोर्ट करें। |
| `trust_tier` | केवल-पठन | किसी पंजीकृत टूल के लिए LOW/MEDIUM/HIGH/CRITICAL टियर और सुधार संकेत प्राप्त करें। |
## सैंडबॉक्स प्रोफ़ाइल
| प्रोफ़ाइल | टाइमआउट | अधिकतम stdout | अधिकतम stderr | FD बजट | cgroup-v2 |
|---------|---------|-----------|-----------|-----------|-----------|
| `strict` | 5 s | 1 MB | 256 KB | 32 | हाँ (cpu/memory) |
| `standard` (डिफ़ॉल्ट) | 30 s | 10 MB | 1 MB | 256 | हाँ |
| `permissive` | 5 min | 100 MB | 10 MB | 1024 | नहीं |
कॉलर प्रति कॉल `timeoutMs` / `fdBudget` के माध्यम से कड़ा कर सकता है। कॉलर प्रोफ़ाइल से
आगे नहीं बढ़ा सकता।
## ट्रस्ट टियर
| टियर | शर्त |
|------|-----------|
| LOW | टूल पंजीकृत नहीं (डिफ़ॉल्ट-अस्वीकार) |
| MEDIUM | पंजीकृत लेकिन `argsPatterns` खाली (कोई भी args अनुमत) |
| HIGH | `argsPatterns` सेट लेकिन सैंडबॉक्स या रीप्ले ट्रैकर निष्क्रिय |
| CRITICAL | argsPatterns + सैंडबॉक्स + रीप्ले सभी सक्रिय |
टूल को पंजीकृत करके + argsPatterns सेट करके + `guardExec`/`guardSpawn` के माध्यम से चलाकर
(जो हमेशा सैंडबॉक्स + रीप्ले सक्रिय करते हैं) LOW → CRITICAL तक बढ़ाएँ।
## लाइब्रेरी क्विकस्टार्ट
```ts
import {
AllowlistRegistry,
ReplayWindow,
guardExec,
} from "mcp-stdio-shellguard";
const registry = new AllowlistRegistry();
const replay = new ReplayWindow();
registry.register({
toolName: "git-log",
executable: "/usr/bin/git",
argsPatterns: ["^log$", "^--oneline$", "^-n$", "^\\d+$"],
sandboxProfile: "strict",
});
const result = await guardExec(
{
toolName: "git-log",
command: "/usr/bin/git",
args: ["log", "--oneline", "-n", "10"],
},
{ registry, replay },
);
console.log(result.stdout); // → commit lines
console.log(result.trustTier); // → "CRITICAL"
console.log(result.canonicalHash); // → 64-char SHA-256
```
## ऑडिट CLI
```bash
mcp-shellguard-audit scan ./src
mcp-shellguard-audit scan ./src --format sarif --output audit.sarif
mcp-shellguard-audit scan ./src --severity-floor HIGH # CI gate
```
एक्ज़िट कोड:
- `0` साफ़ (फ़्लोर पर या उससे ऊपर कोई निष्कर्ष नहीं)
- `1` निष्कर्ष मौजूद
- `2` पार्स / IO त्रुटियाँ
`scanPath` या `audit_source` MCP टूल को पास किए गए कस्टम `ignoreGlobs` अधिकतम
128 स्ट्रिंग्स स्वीकार करते हैं। प्रत्येक स्ट्रिंग 1024 UTF-16 कोड यूनिट और 16
अनएस्केप्ड ओपनिंग ग्रुपिंग कैरेक्टर्स (`(`, `{`, `[`) तक सीमित है। इन बजट से
अधिक इनपुट मैचिंग से पहले एक नियंत्रित त्रुटि उत्पन्न करते हैं।
## एंटी-पैटर्न लाइब्रेरी (12 नियम)
| ID | गंभीरता | कब सक्रिय होता है |
|----|----------|-------------|
| `exec_template_literal_with_input` | CRITICAL | `child_process.exec(\`ls ${x}\`)` |
| `exec_dynamic_string` | CRITICAL | `child_process.exec(cmd)` |
| `exec_sync_dynamic_string` | CRITICAL | `child_process.execSync(cmd)` |
| `eval_near_child_process` | CRITICAL | `eval(...)` |
| `function_constructor_near_child_process` | CRITICAL | `new Function(...)` |
| `spawn_dynamic_file_args` | HIGH | `spawn(bin, userArgs)` |
| `exec_file_dynamic` | HIGH | `execFile(bin, ...)` |
| `shell_true_option` | HIGH | `{ shell: true }` |
| `os_system_equivalent` | HIGH | `Deno.run` / `Bun.spawn` |
| `spawn_literal_dynamic_args` | MEDIUM | `spawn('git', userArgs)` |
| `unbounded_buffer` | LOW | `maxBuffer` के बिना exec |
| `missing_timeout` | LOW | `timeout` के बिना exec/spawn |
स्कैनर मैचिंग से पहले *पुनर्नामित* `child_process` बाइंडिंग्स को हल करता है,
इसलिए नीचे दिए गए खतरनाक आकार तब भी पकड़े जाते हैं जब कॉल किसी लिटरल
`child_process.exec` के बजाय किसी उपनाम के माध्यम से जाती है:
- `const execAsync = promisify(exec); execAsync(`...${x}`)`
- `import cp from "node:child_process"; cp.exec(`...${x}`)`
- `const { exec: sh } = require("child_process"); sh(`...${x}`)`
- `import { exec as run } from "node:child_process"; run(...)`
सिंक्रोनस वेरिएंट्स (`spawnSync`, `execFileSync`) अपने async नियम साझा करते हैं,
और `shell_true_option` एक स्ट्रिंग शेल (`{ shell: "/bin/sh" }`) या किसी
डायनामिक शेल मान पर भी सक्रिय होता है — केवल लिटरल `{ shell: true }` पर नहीं।
किसी गैर-child_process फ़ंक्शन का `promisify`, किसी अन्य मॉड्यूल से डीस्ट्रक्चर,
और `{ shell: false }` साफ़ रहते हैं (कोई गलत पॉज़िटिव नहीं)।
## प्रैग्माज़
- `// shellguard:ignore-next-line` — एक निष्कर्ष को दबाएँ
- `// shellguard:ignore-file` — पूरी फ़ाइल को दबाएँ (दुर्लभ; प्रति-पंक्ति को प्राथमिकता दें)
## यह क्यों मौजूद है
Ox-Security ने खुलासा किया (2026-05) कि 200k+ MCP stdio सर्वर `child_process.exec`
को टेम्पलेट लिटरल्स के साथ रैप करते हैं जो सीधे LLM टूल आर्ग्स से आने वाले
उपयोगकर्ता इनपुट को ले जाते हैं। LiteLLM v1.83.6 इसका प्रामाणिक उदाहरण था
(CVE 1.83.7 में पैच किया गया)। यह बंडल रक्षात्मक-सुरक्षा समकक्ष है: एक ड्रॉप-इन
गार्ड + स्कैनर जो इस वर्ग को बंद करता है। AWS Linux `seccomp` + Chromium
सैंडबॉक्स टियर्स से प्रेरित।
## यह भी देखें
- `HOOK_RECIPES.md` — Claude Code हुक रेसिपी जो खतरनाक टूल कॉल्स को स्वतः ब्लॉक करती हैं
- `CHANGELOG.md` — रिलीज़ इतिहास
- Ox-Security MCP ऑडिट: <https://venturebeat.com/security/200000-mcp-stdio-servers/>
- LiteLLM CVE-2026-XXXX: <https://github.com/BerriAI/litellm/security/advisories>
## लाइसेंस
MIT — Copyright (c) 2026 Matthias Meyer (StudioMeyer)