Skip to main content

Active, confirmation-driven security scanner for MCP (Model Context Protocol) servers - Burp Active Scan, for MCP.

Project description

mcpsnare

The active security scanner for MCP servers — Burp Active Scan, for the Model Context Protocol.

ci Python License: MIT

mcpsnare enumerates the tools an MCP server exposes, fires targeted payloads at their parameters, and reports only what it can prove. Every finding is tied to a concrete oracle — an out-of-band callback, a reflected canary, a calibrated timing delay — and carries a graded confidence level.

Most "MCP security" tools pattern-match configs and source code. mcpsnare triggers the vulnerability and catches the proof: a CONFIRMED finding is exploitable, not theoretical.

(Formerly published as mcprobe.)

Demo

A default scan of a vulnerable MCP server — no config, one command:

$ mcpsnare scan --stdio "python vulnerable_server.py"
[!] mcpsnare - authorized testing only.

6 finding(s):
  [HIGH]      Path traversal in read_doc.path         (confirmed)
  [HIGH]      Secret/info leak via whoami             (firm)
  [HIGH]      Path traversal in read_cfg.config.path  (confirmed)
  [HIGH]      Path traversal in read_many.paths[0]    (confirmed)
  [HIGH]      Path traversal in read_mode.path        (confirmed)
  [CRITICAL]  Command injection in ping.host          (confirmed)

That CRITICAL command injection is confirmed because the injected payload made the target call back to a listener mcpsnare controls — an out-of-band proof of execution, not a guess. The same scan as machine-readable JSON (or SARIF / Markdown):

$ mcpsnare scan --stdio "python vulnerable_server.py" --output json
{
  "summary": { "critical": 1, "high": 5, "medium": 0, "low": 0, "info": 0 },
  "findings": [
    {
      "check": "path_traversal", "tool": "read_doc", "param": "path",
      "severity": "high", "confidence": "confirmed", "cwe": "CWE-22",
      "title": "Path traversal in read_doc.path",
      "payload": "../../../../../../etc/passwd",
      "evidence": "root:x:0:0:root:/root:/bin/bash",
      "remediation": "Resolve and contain paths within an allowed base dir."
    }
    /* ... */
  ]
}

Install

From source (Python 3.11+):

git clone https://github.com/Den-Sec/mcpsnare && cd mcpsnare
pip install -e ".[dev]"

This installs the mcpsnare console entry point. A PyPI release (pipx install mcpsnare) is imminent — see Releases.

Quickstart

# Local stdio server (launched as a subprocess)
mcpsnare scan --stdio "python server.py"

# Remote streamable-HTTP endpoint, with auth, emitting SARIF for code scanning
mcpsnare scan --http https://host/mcp --header "Authorization: Bearer X" --output sarif

# Add blocking time-based probes (off by default) and tune concurrency
mcpsnare scan --stdio "python server.py" --aggressive --concurrency 8

Why mcpsnare

Most MCP security tooling is either a generic fuzzer (noisy, low-signal) or a defensive/static analyzer (reads config and source, never proves exploitability). mcpsnare is built around active confirmation:

  • Oracle-backed, not guesses. Every finding is tied to a concrete signal: an out-of-band (OOB) callback, a calibrated time delay, a canary value reflected in the response, or a baseline diff. No signal, no finding.
  • Graded, calibrated confidence. Findings carry an explicit confidence level (CONFIRMED / FIRM / TENTATIVE, see Confidence levels). Per-tool baseline calibration suppresses the usual false-positive classes — a slow-but-safe tool, or output that merely looks secret-shaped, is not flagged.
  • Reaches real schemas. Maps injection points through nested objects, array items, and params gated behind required enums; builds schema-valid baselines so payloads actually reach the handler.
  • Both transports. Works against MCP servers over stdio (local process) and streamable HTTP (remote endpoint, with custom headers/auth) — both exercised end-to-end in CI on Linux and Windows.

Confidence levels

Every finding carries one of three confidence levels, each earned by a specific oracle:

Level Meaning How it's earned
CONFIRMED The payload provably executed, or protected data was reached. An out-of-band callback fired (cmd injection, SSRF), a canary value was read back (path traversal), or an unauthenticated call returned a response byte-identical to the authenticated one (auth bypass).
FIRM A calibrated/inferred signal strongly indicates the issue, short of an OOB proof. A response delay exceeds the per-tool calibrated baseline by the injected sleep (time-based cmd injection); a secret-shaped string appears in the probe response but not in the benign baseline (info leak); or an unauthenticated response matches the authenticated one only after stripping volatile fields like timestamps/ids (auth bypass).
TENTATIVE Pattern-only match, with no calibration to corroborate it. A secret-shaped string matched, but no baseline was available to prove the input triggered it — review manually.

The OOB and canary checks emit only CONFIRMED. Auth-bypass emits CONFIRMED on a byte-identical response or FIRM on a match after stripping volatile fields. The timing and info-leak oracles are where FIRM and TENTATIVE arise.

Checks

Check Vulnerability CWE
cmd_injection OS command injection CWE-78
ssrf Server-side request forgery CWE-918
path_traversal Path traversal CWE-22
auth_bypass Missing authentication CWE-306
info_leak Secret / sensitive info leak CWE-200
sql_injection SQL injection CWE-89

mcpsnare also enumerates MCP resource templates and treats their templated URI params (e.g. file:///{path}) as injection points for path-traversal and info-leak.

Out-of-band (OOB) confirmation

OOB callbacks are how mcpsnare confirms blind command injection and SSRF: a probe makes the target reach back to a listener mcpsnare controls.

  • --oob local (default) spins up an in-process HTTP listener on localhost. It needs no external service and works for targets that can reach your machine (typically local stdio servers).
  • --oob interactsh uses an out-of-band interaction server for targets that cannot reach localhost (e.g. remote HTTP servers). mcpsnare ships a real interactsh client (RSA-OAEP / AES-256-CTR), so this works out of the box against the public oast.fun (override with --interactsh-server); it was live-verified end to end. See docs/interactsh-runbook.md.
  • --oob none disables OOB confirmation; only time-based and canary oracles run.

Flags

  • --stdio "<cmd>" / --http <url> — target transport (one required).
  • --header "k:v" — add an HTTP header (repeatable).
  • --oob {local,interactsh,none} — OOB confirmation backend (local default).
  • --aggressive — also send blocking time-based (sleep) probes; by default mcpsnare sends only non-blocking OOB/canary/pattern probes (time-based detection is aggressive-only).
  • --concurrency N — max concurrent probe requests (default 4). Time-based probes run serially.
  • --rate R — cap to R requests/second (default unlimited).
  • --oob-timeout S / --oob-poll-interval S — how long (default 20s) / how often (default 2.5s) to poll for OOB callbacks.
  • --output {console,json,sarif,md} — output format (default console).

Authorized testing only

mcpsnare is an active scanner. It sends real, potentially destructive payloads to the target. Run it only against systems you own or have explicit written authorization to test. Unauthorized use may be illegal. You are responsible for how you use this tool.

Validation

mcpsnare is validated by an automated test suite (119 tests) against bundled deliberately-vulnerable fixture servers in tests/fixtures/. The suite exercises command injection (including cross-OS cmd.exe / PowerShell payloads), SSRF, path traversal, info-leak, SQL injection, nested/array/enum injection points, and the OOB, baseline-calibration, and false-positive-suppression paths end to end — over both stdio and a live in-process streamable-HTTP server, on Linux and Windows in CI. See docs/claims-matrix.md for the claim-to-test mapping.

It has also been smoke-tested against the real @modelcontextprotocol/server-everything reference server (13 tools, 2 resource templates) — clean run, zero false positives. See docs/smoke-run.md.

Roadmap

  • MCP-specific checks: tool-poisoning / prompt-injection via tool descriptions, and tool-scope / permission-boundary violations.
  • Additional OOB providers and richer time-based oracles.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcpsnare-0.3.0.tar.gz (39.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcpsnare-0.3.0-py3-none-any.whl (29.2 kB view details)

Uploaded Python 3

File details

Details for the file mcpsnare-0.3.0.tar.gz.

File metadata

  • Download URL: mcpsnare-0.3.0.tar.gz
  • Upload date:
  • Size: 39.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mcpsnare-0.3.0.tar.gz
Algorithm Hash digest
SHA256 95623a1b31a2b710ba58ae63f90d7ec573faf35bf03830b75c0e67473dc7f52e
MD5 3f2af3683066a53e751746f1037400e7
BLAKE2b-256 9f9c5ec49d8c22276636e9c2e51e7b5638c09a958e256218f3d578750dac7817

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcpsnare-0.3.0.tar.gz:

Publisher: release.yml on Den-Sec/mcpsnare

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mcpsnare-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: mcpsnare-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 29.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mcpsnare-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 83dbcac2ea43c8a1e54fb0ed832ed79cc584f65c514fe922a169b691de8ad3f4
MD5 aa1cbff8fe58d778aab8b219028ff09a
BLAKE2b-256 f438823ec0d59a4d12145ecc4ac0a229b46e1a6b523f606336ef7b08efff0d59

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcpsnare-0.3.0-py3-none-any.whl:

Publisher: release.yml on Den-Sec/mcpsnare

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page