Skip to content

mcpsnare 0.5.0 — confirm the code sink + honest reports

Latest

Choose a tag to compare

@Den-Sec Den-Sec released this 23 Jul 07:02

The passive lens flagged an execute_revit_code-style tool; the active checks couldn't
confirm it, because shell metacharacters are a SyntaxError inside a language interpreter.
And a bare results: [] couldn't be told apart from "nothing was actually tested". This
release closes both — and adds a check that speaks the sink's language.

Highlights

  • Active code / eval-sink injection (code_injection, CWE-94). Injects language-native
    payloads — CPython urllib, Python 2 / IronPython urllib2, Node require('http') — each
    with its own out-of-band token, plus an arithmetic canary (7*7 → 49) whose evaluation is
    reflected in the response. CONFIRMED on an OOB callback, FIRM on the canary absent from
    the benign baseline, TENTATIVE without a baseline; a time.sleep variant is
    --aggressive-only. Gated to code-shaped parameter names. A bundled code_server fixture (a
    real eval/exec sink) confirms it in CI — a payload really opens a socket to the local
    listener, no Revit needed. This turns a declared code-exec tool from flagged into confirmed.

  • Scan metadata in every report (ScanResult). Reports now carry target, transport, tools
    discovered vs. reachable, checks run, --aggressive, and how many injection points skipped the
    blocking time-based probes — so an empty findings is distinguishable from an untested scan
    (JSON scan, SARIF invocations, a Markdown "Scan metadata" section; a console header on the CLI).

  • Free-form container coverage. Injection-point mapping now reaches values inside open maps —
    additionalProperties, a bare dict, list[dict] — so a modify_element(parameters: dict)
    tool is probed via a synthesized canary key instead of skipped. Structured objects untouched.

  • Unauthenticated-privileged-proxy note (privileged_proxy, CWE-306, INFO). When the manifest
    declares a CRITICAL/HIGH capability and the scan reached the tools with no credential presented,
    the note flags the surface to vet — honestly stating the auth boundary was not verified, never
    that it's absent.

Also

  • Confidence-aware dedup: a later, stronger oracle (a deferred OOB CONFIRMED) upgrades an
    earlier weaker finding for the same issue instead of being dropped.
  • Real-OS-shell validation: cmd-injection is now OOB-confirmed against a real shell (cmd.exe on
    Windows, /bin/sh on POSIX) on the CI matrix, closing the "fake-shell only" caveat for the
    common (non-PowerShell) shell path.

Fixed (found by scanning real servers)

  • Crash on tools-only servers. resources/templates/list is optional in the MCP spec; a
    tools-only server (most real servers) answers "Method not found". mcpsnare treated that as fatal
    and aborted the whole scan — it now tolerates it and continues.
  • Ungraceful start failure. A server that exits before the MCP handshake (missing credentials,
    bad command) now yields a clean error + non-zero exit instead of a raw traceback.

52 new tests; suite is now 191 green across Linux + Windows CI. No breaking changes to callers
or report consumers. Every public claim is mapped to a passing test in
docs/claims-matrix.md.

Field-tested: run against real official @modelcontextprotocol servers — it confirmed an
unauthenticated SSRF in the reference server, kept zero false positives (the filesystem
sandbox held against path-traversal), and the two fixes above came straight out of that run. The
honest field report is in
docs/real-world-scan-2026-07.md.

Install / upgrade: pipx install mcpsnare (or pip install -U mcpsnare).