Repository navigation
security: tool description pinning, injection scan, DNS rebinding default fix - #3754
Closed
Ablation-Tool wants to merge 1 commit into
Closed
Ablation-Tool wants to merge 1 commit into
Ablation-Tool wants to merge 1 commit into
Conversation
…ault Three security fixes identified via full static audit of the Python SDK: 1. client/session.py — add protocol-version-agnostic security pass to _absorb_tool_listing(): SHA-256 description pinning blocks rug-pull attacks (tools/list_changed re-fetch accepts poisoned descriptions silently); regex injection scan drops tools with prompt injection patterns on first sight. 2. server/transport_security.py — flip enable_dns_rebinding_protection default from False to True; add startup WARNING when allowed_hosts is empty so misconfigured deployments fail visibly, not silently. 3. cli/cli.py — remove shell=True from Windows npx probe subprocess call (CWE-78; cmd values are hardcoded today but shell=True with a list is exploitable if ever made configurable). Signed-off-by: Nicholas Michael Kloster <nicholas@nuclide-research.com> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
|
This PR has been closed automatically. This repo only keeps pull requests open when they come from a maintainer, or from a contributor a maintainer has assigned to the linked issue, and this PR doesn't link an open issue yet.
You're welcome to keep pushing commits here (just avoid force-pushing, since GitHub can't reopen a rewritten branch), but that on its own won't get the PR reviewed or the issue assigned, and realistically most auto-closed PRs stay closed. There's no need to open a new PR either way. CONTRIBUTING.md has the full reasoning, but in short:
Maintainers: reopen, remove |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes three security issues identified during a full static audit of the Python SDK (128 files, ruff + pyright clean, 244 tests pass):
Rug-pull attack (CWE-345):
_absorb_tool_listing()accepted re-fetched tool descriptions after atools/list_changednotification with no integrity check. A malicious server can serve clean descriptions for N interactions, then send the notification and return poisoned descriptions on re-fetch. Fix: SHA-256 pin each description on first sight; any subsequent change drops the updated version and logs a security warning. Runs for all protocol versions (not gated on modern-only).Tool description injection (CWE-20):
_absorb_tool_listing()validatesx-mcp-headerannotations and output schemas but never inspectstool.description— the field sent verbatim to the LLM context. Fix: regex scan against known prompt-injection patterns before pinning; drops tools that match on first sight.DNS rebinding protection off by default (CWE-16):
TransportSecurityMiddlewaredefaulted toenable_dns_rebinding_protection=Falsefor backwards compatibility. Fix: flip default toTrue; add a startupWARNINGlog whenallowed_hostsis empty so misconfigured deployments fail visibly rather than silently rejecting all requests.CWE-78 in CLI npx probe:
subprocess.run([cmd, "--version"], shell=True)on Windows.cmdis currently hardcoded, butshell=Truewith a list is exploitable if ever made configurable. Fix: removeshell=True.Changed files
src/mcp/client/session.py_INJECTION_PATTERNS,_tool_desc_hash(),_scan_tool_description(); security pass in_absorb_tool_listing()src/mcp/server/transport_security.pyTrue; add empty-allowed_hostsstartup warningsrc/mcp/cli/cli.pyshell=Truefrom npx probeTest plan
pytest tests/client/ tests/transports/ tests/cli/— 244 passed, 4 skipped (verified locally)ruff checkon all three files — cleanpyrighton all three files — 0 errors, 0 warningsBackground
These vectors were originally documented as part of the DEADBUG-MCP research series (rug-pull V3, cross-server poisoning V4). The rug-pull fix described by MCP Playground ("pin the tool definitions you approved, call the server several times, list again, and treat any difference as a security event") is now implemented at the SDK level in
_absorb_tool_listing().Signed-off-by: Nicholas Michael Kloster nicholas@nuclide-research.com
🤖 Generated with Claude Code