2026-07-30T17:16:02.562Z
MCP Security Vulnerabilities: Prove Exposure Before You Patch
Turn an MCP advisory into a runtime-specific exposure receipt, then verify the tool and intended outcome after remediation.
When an MCP vulnerability lands in your feed, the first operational question is not “how severe is the headline?” It is: does this advisory reach a component that is actually running in my agent path? Answer that before executing an exploit, mass updating every package, or declaring a clean scan sufficient. A defensible verdict joins five pieces of evidence: 1. the exact advisory and package identity; 2. the installed and launched version; 3. the advisory publisher’s affected range result; 4. the vulnerable entry point’s reachability and any temporary mitigation; 5. a post remediation tool probe plus a receipt for the intended task outcome. That join produces a small set of useful states: absent , unknown , not affected , affected not reachable , exposed , patched unverified , remediation regression , or remediated . It also stops two dangerous shortcuts: treating package presence as confirmed exposure, and treating a successful upgrade command as recovery. Build the exposure join before choosing the response A vulnerability catalog is useful for discovery, but it is not your runtime inventory. The advisory may name a package that appears only in a lockfile, an abandoned environment, a container layer that is never launched, or a transitive development dependency. The reverse failure is worse: an MCP client can launch a package through a wrapper or global install that your repository scan never inspected. Collect the evidence from the runtime boundary that owns the MCP process. Do not upload prompts, tool arguments, tokens, absolute paths, or business data. A compact receipt can look like this: The matchStatus should come from a package manager, SBOM tool, or structured advisory feed that understands the ecosystem’s version syntax. Do not compare version strings lexically. The reviewed GitHub advisory for mcp remote , for example, records = 0.0.5, < 0.1.16 as affected and 0.1.16 as the first patched version. The reviewed advisory for @modelcontextprotocol/server filesystem contains both a legacy range and a date based line, with 2025.7.1 as the first patched release for that line. One hand written comparator is a poor place to normalize both schemes. Package and version evidence still do not settle reachability. The current versioned MCP Security Best Practices illustrates why configuration matters. Its confused deputy analysis lists several conditions that must coincide, including a proxy using a static third party client ID, dynamic client registration, a consent cookie, and missing per client consent. The same guidance and the MCP authorization specification forbid token passthrough and require the resource server to validate that a token was issued for it. Those controls should become fields in an exposure specific receipt, not a generic “security enabled” checkbox. For an authorization advisory, collect audience validation, redirect matching, consent ownership, and proxy behavior. For a filesystem advisory, collect the launched server version, allowed roots, reachable tool surface, and the exact mitigation that makes the affected entry point unavailable. For a command injection advisory, collect the client wrapper, version, remote server trust boundary, and whether that connection route can be invoked. An affected component with a verified disabled entry point is affected not reachable , not not affected . That is useful containment evidence, but it expires. Record an owner and deadline for the patch because a configuration edit, deployment rollback, or new client can make the path reachable again. Run a content free classifier, not an exploit You do not need a weaponized payload to route the incident. The following decision rule is deliberately conservative: The state names encode the next decision: State What the evidence proves Bounded next action absent The named component is not present at the inspected runtime boundary Record inventory scope and close for this boundary unknown Identity, version, advisory match, or reachability is missing or conflicting Preserve uncertainty; resolve the first missing field not affected The installed component is outside the publisher’s affected range Retain source and freshness; do not infer protection from a similar package name affected not reachable The affected code exists, but the named entry point is blocked by verified containment Keep containment, assign patch owner, and set an expiry exposed Affected version and reachable entry point coincide Contain the path, revoke unnecessary authority, and patch patched unverified The version moved out of range, but functional evidence is incomplete Run a safe canary tool probe and verify the expected destination remediation regression The patch or containment broke the required tool or outcome Keep the risky path contained; repair compatibility or use a reviewed rollback remediated Version, safe tool behavior, and intended outcome all pass Monitor freshness and close with the evidence receipt I ran that rule over eight content free cases, one for each state. All eight matched the expected result. The inconvenient case is the most valuable: @modelcontextprotocol/server filesystem is on the advisory’s patched release, but its safe tool probe fails. The classifier returns remediation regression , not remediated . That boundary matters because security work can create an agent health incident. A dependency update may change a launch command, capability schema, allowed root, OAuth flow, or client compatibility. The vulnerable code can be gone while the agent’s required work is still broken. The receipt has limitations. It does not prove that an unknown exploit cannot reach the component. It does not replace forensic evidence after suspected compromise. It also depends on accurate package identity and current advisory data; if two sources disagree, return unknown and preserve both references. The NVD record for CVE 2025 6514, for example, provides an additional dated record for the mcp remote command injection issue, but the package range should still be tied to the exact reviewed advisory used by your matcher. Patch in a sequence that preserves agent health Containment and remediation need separate approvals because their blast radii differ. A practical sequence is: 1. Freeze identity. Record the advisory ID, package, launched version, client or server owner, and evidence time. 2. Contain the named path. Disable the vulnerable server, remote connection, tool, or authorization route with the smallest reversible change available. 3. Reduce authority. Revoke unnecessary credentials and permissions associated with that component. Rotate a secret only when exposure evidence or policy requires it; rotation can destroy useful evidence and create unrelated outages. 4. Install the publisher supported fix. Use the named patched line, not an arbitrary latest version, and retain the package manager result. 5. Restart the real owner. Updating a lockfile or image tag is not enough if a long running agent client still owns the old process. 6. Run a safe tool probe. Use a synthetic, least privilege target. Do not replay the exploit or point the canary at production data. 7. Verify the destination outcome. Confirm the file, ticket, record, message, or other expected result exists and is correct. 8. Watch a stability window. Check that the component stays reachable when expected, does not re enter the vulnerable range, and does not fail repeatedly after the patch. Keep the tool probe distinct from the outcome receipt. A filesystem tool can return success while writing to the wrong allowed root. A ticket tool can accept a request while the record is later rejected. An MCP transport can remain healthy while the agent’s deliverable is missing. The first receipt proves the repaired capability can execute safely; the second proves the user’s work actually arrived. Close the incident only when the strongest available evidence agrees: the advisory no longer matches the launched component, the formerly vulnerable path is controlled, the safe canary passes, and the intended outcome is present. If any field is stale or contradictory, keep the state explicit instead of coloring it green. Sidewisp is currently in private preview. Its product direction is a health layer for existing agent runtimes: surface concrete evidence, distinguish working from waiting or stuck, keep human approval at the action boundary, and verify outcomes after intervention. The current public experience is an early access demonstration, not a shipped MCP scanner, monitoring adapter, or automated recovery engine.