ESLint security rules for MCP servers — catches SANDWORM_MODE credential harvesting, path traversal, command injection, and CVE patterns at dev time
Drift inferred · capture-to-capture
No drift recorded — single capability capture; advisories appear once its surface changes.
transport http counts 5 tools · 0 res
· 0 prompts
permission surface via README inference
tools
-
fetch_repo
-
get_env
-
index_project
-
read_file
-
run_cmd
prompt-surface
shipped agent-instruction files + hidden-content / dangerous-code findings —
quoted from the analyzed source
analyzed commit 447e9bc · analyzer v33 · 1w ago
danger signals4
- dynamic code execution eval() mattschaller-eslint-plugin-mcp-security-447e9bc/example/bad-server.ts :29
eval(params.path); - dynamic code execution eval() mattschaller-eslint-plugin-mcp-security-447e9bc/tests/rules/security/no-eval-in-handler.test.ts :23
const result = eval("1 + 1"); - dynamic code execution new Function() mattschaller-eslint-plugin-mcp-security-447e9bc/tests/rules/security/no-eval-in-handler.test.ts :53
const fn = new Function("return " + params.code); - dynamic code execution vm exec mattschaller-eslint-plugin-mcp-security-447e9bc/tests/rules/security/no-eval-in-handler.test.ts :63
vm.runInNewContext(params.code, {});
evidence-backed
findings quoted directly from the published source artifact — not inferred
code files: 32
filesystem 2
- fs (weak) mattschaller-eslint-plugin-mcp-security-447e9bc/example/bad-server.ts :3
import { readFileSync } from "fs"; - fs mattschaller-eslint-plugin-mcp-security-447e9bc/src/rules/security/no-unscoped-tool-permissions.ts :17
'rmdir', // fs.rmdir
shell / exec 4
- shell (weak) mattschaller-eslint-plugin-mcp-security-447e9bc/example/bad-server.ts :2
import { execSync } from "child_process"; - shell mattschaller-eslint-plugin-mcp-security-447e9bc/src/utils/mcp-ast-helpers.ts :168
* Handles both direct calls (exec()) and member expressions (cp.exec()). - shell (weak) mattschaller-eslint-plugin-mcp-security-447e9bc/tests/rules/security/no-shell-injection-in-tools.test.ts :23
const result = execSync("ls"); - shell (weak) mattschaller-eslint-plugin-mcp-security-447e9bc/tests/rules/security/no-unvalidated-tool-input.test.ts :59
exec(cmd);
secrets 3
- secrets (weak) mattschaller-eslint-plugin-mcp-security-447e9bc/example/bad-server.ts :32
const secret = process.env.SECRET_KEY; - secrets (weak) mattschaller-eslint-plugin-mcp-security-447e9bc/tests/rules/security/no-hardcoded-secrets-in-server.test.ts :16
code: `const apiKey = process.env.API_KEY;`, - secrets (weak) mattschaller-eslint-plugin-mcp-security-447e9bc/tests/rules/security/no-sensitive-data-in-tool-result.test.ts :38
const key = process.env.API_KEY;
install hooks 1
- prepublishOnly mattschaller-eslint-plugin-mcp-security-447e9bc/package.json :22
npm run build && npm run test
declared dependencies 8
- @types/node@^25.5.0
- @typescript-eslint/parser@^8.57.0
- @typescript-eslint/rule-tester@^8.57.0
- @typescript-eslint/utils@^8.57.0
- @vitest/coverage-v8@^4.1.0
- eslint@^10.0.3
- typescript@^5.5.0
- vitest@^4.1.0