Skip to content

Releases

v1.6.0: Runtime Protection

Choose a tag to compare

@Paraphern Paraphern released this 07 Nov 17:41

What's new

Three security layers from an external ChatGPT-agent contribution, independently verified across three REVIEW passes:

Startup Pin Verification

Before any proxy or CLI runtime spawns a server, the Ed25519 signature of pins.json is verified against pins.sig. A tampered store throws at startup. Hex validation prevents silent truncation. An invalid committed key no longer silently falls back. Semantic change: orphan-sig is now tampered (strict fail-closed).

Runtime Auto-Quarantine

In enforce mode, drifted tools are blocked at CALL time (JSON-RPC error -32603), not just stripped from tools/list. Per-tool, not per-server. HTTP responses correlated by request-ID. The P2-1 race (pipelined call before first tools/list) is closed fail-closed. Semantic change: UNCHANGED-unapproved tools now quarantined.

Canary Response Shapes

Replay validation compares every distinct array element structure, preserves JSON property names, accounts for MCP isError outcomes. __proto__ protection via Object.defineProperty.

526 tests (+120 since 1.5.0) · zero dependencies · no telemetry · on-chain verified (Base Mainnet)

v1.5.0

Choose a tag to compare

@Paraphern Paraphern released this 19 Oct 06:52

What's new

  • outputSchema pinning (R14) - a third hash outputHash pins what tools RETURN, not just what they accept. A server that quietly widens its response shape is drift now.
  • Resource content pinning (R13-full) - resources/read on up to 20 envelope-only resources; the prompt-injection payload hidden in a resource body is a finding, not a surprise.
  • annotations.title pinned + icons in toolHash - a silent rename from "Safe File Reader" to "Data Export Utility" is ANNOTATION drift. Ships with the policyVersion bump: legacy pins get POLICY stop, never a silent re-grade.
  • MIRRORED class + OpenAPI crosscheck (R35/R36) - tighten changes the vendor's published spec already promised are regraded BREAKING -> MIRRORED via diff --openapi <spec>. BREAKING now means "a previously-successful call starts failing".
  • scan --prune (R37) - drop departed servers/tools/skills/prompts from the pin store on purpose.
  • A19: payment-credential exfiltration - descriptions instructing the agent to POST card numbers/CVC/expiry. Zero FP on 1152 benign descriptions.
  • A20: hidden directive blocks (FORCED) - <IMPORTANT>/<NOTE TO AGENT> tags (attributes + hyphenated variants), ChatML markers, [//]: # markdown stubs, HTML comments carrying directive text. Benign build markers and linter pragmas stay clean. Class surfaced by the mcp-shield comparison (teleport#61434).
  • CI badge (https://rugsnare.com/badge/:owner/:repo.svg), GitHub composite Action, richer PR-comment renderer, Smithery .mcpb bundle.
  • Preverification fixes: outputHash in the skip-guard, contentHash preserved by approve; signed pins restored for the corpus and repo root.

384 tests, zero dependencies, no telemetry. On-chain pin follows shortly.

RugSnare 1.4.3 - POLICY stop-rule (PIN-SPEC §3.1)

Choose a tag to compare

@Paraphern Paraphern released this 17 Oct 02:08

When the pin store's policyVersion differs from the running binary, diff now emits the POLICY finding and STOPS - exactly one finding, no tool-level classes (BREAKING, LOOSENED, COSMETIC, GONE, NEW) follow. Each re-graded class would look like ordinary drift to anyone who scrolled past the POLICY line. The spec says "stops for that pin", and now the code does too. Exit 1 with a hint: "re-run after rugsnare scan to grade under the current policy".

359 tests. Verified: sha256 57483327...6727 matches the on-chain pin. Native launcher unchanged (1.3.0-native.1).

RugSnare 1.4.2 - §7 byte-stability for skills, prompts and resources

Choose a tag to compare

@Paraphern Paraphern released this 14 Oct 15:22

All three pin branches (tools, skills, prompts/resources) now share the same skip-guard pattern: a re-scan of unchanged content leaves the entry untouched. Before this fix, pinAllSkills rewrote pinnedAt on every scan (293/293 entries in a field diff), and cmdScan rewrote firstSeen for prompts and resources. The Go native launcher is fixed in the same pass.

359 tests. Verified: artifact sha256 d3f9d643...a71a matches the on-chain pin. Native launcher unchanged (1.3.0-native.1) - binaries attached, rebuilt from the tagged tree.

RugSnare 1.4.1 - skills pin paths are now relative (PIN-SPEC §2)

Choose a tag to compare

@Paraphern Paraphern released this 14 Oct 10:16

Patch release: skills pin path field is now stored relative to the skill root instead of machine-absolute (PIN-SPEC §2). The 1.4.0 writer emitted absolute paths, breaking byte-stability across machines (the same skill tree scanned from two different directories produced different bytes) and leaking local layout in published catalog snapshots. Fixed in both the JS CLI and the Go native launcher; pre-v1.4.1 pins with absolute paths are read via a legacy fallback.

357 tests. Verified: artifact sha256 37cbf185...c80e matches the on-chain pin (pinned via Basescan Write Contract - the contract is source-verified there).

Native launcher: unchanged since 1.3.0 (1.3.0-native.1) - binaries attached for convenience, rebuilt from the tagged tree.

RugSnare 1.4.0 - PIN-SPEC v1.1: identity, policy stamp, byte-stable pins

Choose a tag to compare

@Paraphern Paraphern released this 13 Oct 20:07

PIN-SPEC v1.1 (promised in microsoft/autogen#7353 and snyk/agent-scan#482): every pin carries an identity block (package, resolvedVersion, entryPath, url) bound by an identityHash; a policyVersion stamp with the POLICY drift class (pins graded under an older verifier policy are never silently re-graded - the ruler changes, the vendor did nothing wrong); the IDENTITY drift class (tool hashes intact but the surface is served by a different build/path - supabase moved its stdio entry with contracts unchanged); and byte-stable pins.json (sorted keys, unchanged entries never rewritten, identical saves skip the write - third parties can JCS-hash the file as an opaque record).

Also in this release: paywall-introduction detection ([PAYWALL] flag - "requires a paid plan" rewrites are schema-silent); hosted endpoints in the public drift-feed (first live hosted catch within 40 minutes of a release); contract provenance (resolved zod/SDK versions per capture - a floating schema dep can rewrite a server's contract with no release); launch-entry pinning (bin moves surface even with zero contract findings); pure-expand finally grades EXPANDED (the P5 label was unreachable since 1.2.0); and verify now really defaults to Base Mainnet, as 1.0.1 promised.

354 tests, zero dependencies, no telemetry. Verified end to end: artifact sha256 c78018cc...4ed2 matches the on-chain pin (tx) - and the ReleaseLog contract itself is now source-verified on Basescan.

Native launcher: unchanged since 1.3.0 (1.3.0-native.1) - binaries attached for convenience.

RugSnare 1.3.0 - deep schema analysis, skills parity, ATR cross-references

Choose a tag to compare

@Paraphern Paraphern released this 12 Oct 12:54

Deep schema analysis: schemaDiff now recurses into properties/items/anyOf/oneOf at ANY depth (R21) - changes at depth 2+ are direction-graded for the first time (MongoDB pipeline[][0].$vectorSearch[0].numCandidates, Netlify nested required). Router-union intelligence (R2 cross-tool branch movement, R4 anyOf-to-oneOf keyword swaps graded NOTATION when branches match). Skills: canonical root skills/ (R25), advisory-layer parity via one shared location table - 16 platforms (R26), the .agents/skills standard in both scopes (R27). ATR-compatible: every advisory signal and SARIF rule cross-references the Agent Threat Rules ID for the same technique (docs/ATR-MAPPING.md).

Release re-run fixes, found by re-running the docs/servers pages with this very build: additionalProperties true/{}/absent equivalence (27 false BREAKINGs on the chrome-devtools SDK v2 wave), history --timeout plumbing (flag was parsed but never reached the scanner), R4 swaps no longer grade LOOSENED. New field finding documented as R32: a floating schema dependency (zod ^4.4.3 in mongodb-mcp-server 2.1.2) can rewrite a server's tool contract with no server release.

336 tests, zero dependencies, no telemetry. Verified end to end: npm artifact sha256 af5286af...2fe1 matches the on-chain pin (tx).

Native launcher 1.3.0-native.1 (R25+R27 in its location table) attached for all platforms.

RugSnare 1.2.0 - Drift gradation, constraint keys, rename inference, kill-switch detection

Choose a tag to compare

@Paraphern Paraphern released this 11 Oct 20:53

Four rounds of drift-gradation improvements from the KyttoMCP dialogue (P3-P6, all from @heyitsjakub's feedback), plus scanner robustness from field scans of 10+ npm MCP servers.

Four rounds of drift-gradation improvements from the KyttoMCP dialogue
(P3-P6, all from @heyitsjakub's feedback), plus scanner robustness.

Drift gradation (P3-P6: BREAKING / LOOSENED / EXPANDED / NOTATION)

  • Direction-aware grading (P3+P4): schema drift now grades by direction.
    BREAKING = tighten (new required params, narrowed types, added constraints -
    agent must send more, new data channels are exfil-risk). LOOSENED = loosen
    (constraints dropped, types widened, parameters removed - validation
    weakened, still exit 1 but a distinct failure mode). NOTATION = semantically
    empty (dialect switch only). Mixed tighten+loosen = BREAKING (conservative).
    Validated on chrome-devtools-mcp 1.8.0-1.10.1: 30 former BREAKING findings
    now read 30 NOTATION + 0 BREAKING (the MCP SDK v2 migration wave was pure
    notation).
  • EXPANDED direction (P5): a new optional parameter labels EXPANDED
    instead of riding under tighten - backwards-compatible for callers but
    attack surface widened (a new context param is a classic exfil vector).
    Same exit 1, same severity slot as BREAKING; the label just stops
    semver-literate reviewers from reading "breaking" on a non-breaking change.
  • Guard-parameter warnings (P5+P6): when a schema removes, defangs, or
    flips the default of a guard parameter (dry_run, confirm, force,
    safe_mode...), the diff adds a context-specific warning. Conditional on
    additionalProperties (AP:false = loud failure, no silent-ignore warning).
  • Constraint keys (R3, from MongoDB field scans): schemaDiff now detects
    minItems, maxItems, minimum, maximum, minLength, maxLength, pattern,
    multipleOf, uniqueItems, exclusiveMinimum/Maximum, and number-integer
    transitions. Previously invisible (NOTATION on real constraint changes).
  • Default value tracking (P6): schemaDiff compares default values for
    all parameters (previously invisible - schemaHash changed but schemaDiff
    returned [], grade=NOTATION).

Scanner robustness

  • Publish-time version ordering (R10, playwright bug): history now
    sorts versions by npm publish timestamp, not semver. Packages with two
    versioning epochs (1.52.0-alpha from 2025 semver-older than 0.0.x from
    2026) no longer produce phantom cross-epoch pairs.
  • Rename inference (R11, azure-devops flagship): GONE+NEW tool pairs
    with identical schema+prose hashes collapse into RENAMED a -> b -
    the azure case goes from 104 scattered lines to readable
    "renamed: N, really-gone: M, new: K".
  • Kill-switch classification (R12, bybit case): unreachable versions
    now carry a cause (KILLSWITCH / GATED / GIT_DEPS / CRASH / TIMEOUT)
    based on stderr pattern matching - a remote kill-switch is visible as
    a systematic finding, not a generic "exited early".
  • --server-args flag for rugsnare history: per-package launch
    arguments (e.g. LaunchDarkly needs start --transport stdio). Passed
    as a fixed array after the entry point - no shell, no interpolation.
  • --stub-env flag for rugsnare history: injects presence-only dummy
    values for common credential env vars - servers that only check key
    presence at boot now enumerate their tools/list.
  • Version stamp in output: rugsnare diff and rugsnare history print
    the running rugsnare version in the footer (prevents stale-binary
    debugging sessions when comparing outputs).
  • Pins-version mismatch warning (R1/R9): rugsnare scan records the
    package version it scanned against; rugsnare diff warns when the pins
    were taken against a different version than what's currently installed
    ("if you just upgraded: re-scan first").
  • openai-mcp added to --chameleon rotation (R6): Netlify officially
    serves 21 granular tools to openai-mcp vs 9 routers to other clients.

Corpus and docs

  • Corpus 05: key-reorder fixture (corpus/05-key-reorder/): two
    servers with semantically identical schemas in different key order;
    rugsnare diff reports clean (canonicalization proof). Requested by
    @heyitsjakub as a fixture for KyttoMCP#12.
  • Open Pin Format specification drafted at docs/PIN-SPEC.md (internal;
    publication gated on ecosystem timing).
  • Em-dash cleanup: all long dashes replaced with short hyphens across
    source files and documentation (575 replacements).

On-chain: artifact sha256 68d08748... pinned to Base Mainnet (tx 0x5c35...4b13); verify locally with npx rugsnare verify rugsnare-1.2.0.tgz --version 1.2.0 --chain base.

Web: the Runtime scan at rugsnare.com/#history runs rugsnare history in an ephemeral GitHub Actions sandbox - every result links to its public run log. The archive lives at rugsnare.com/scans.

Native launcher (Go, 7 MB, no Node.js needed): unchanged from 1.1.0 - download from v1.1.0 Releases.

RugSnare 1.1.0 — Skills Security, whole-history scanning, native launcher

Choose a tag to compare

@Paraphern Paraphern released this 07 Oct 15:55

Runtime integrity for AI agents. This release adds two whole product surfaces on top of the MCP contract pinning core: Skills Security (your agent's instruction files, 14 platforms) and whole-history scanning (has this npm package ever quietly changed its tool contracts?).

  • Whole-history scanning (new): rugsnare history <package> [--last N] [--from X --to Y] — downloads every published version from the registry
    (tarballs pulled directly, deps installed with --ignore-scripts and
    --legacy-peer-deps), actually runs each version, takes tools/list, and
    diffs consecutive versions with the same split-hash logic. Prints
    was/became per drifted tool; exit 1 on silent changes, exit 2 when no
    version could be started. On the web: the
    Runtime scan button runs the same CLI in an ephemeral GitHub Actions
    sandbox and publishes the result with a link to the public run log as
    evidence; every scan lands in the public archive at rugsnare.com/scans
    (the instant static scan was retired — runtime truth only).

  • Skills Security (new): rugsnare skills scan|diff|report — pin, diff, and
    visually report on AI agent skill files (SKILL.md, .mdc, etc.) across Claude
    Code, Cursor, Windsurf, Continue, ZCode, Copilot, Codex, and Cline.
    Severity classification (DANGEROUS/REVIEW/SAFE) based on content analysis
    of changed lines. HTML report with plain-language was/became diffs and
    actionable recommendations - designed for non-technical users.

  • Native launcher (new): a single Go binary (native/) with the whole
    skills-security half — no Node.js, no npm, double-click and get the HTML
    report in your browser. Reads/writes the same .rugsnare/pins.json
    skills subtree as this CLI (verified interop both directions); the
    servers subtree passes through untouched. Windows/macOS/Linux, ~7 MB.

  • No silent updates, applied to ourselves: rugsnare version prints the
    running version; rugsnare doctor --check-update compares it against the
    npm registry (opt-in, one GET, nothing sent) and links the changelog —
    plain doctor stays fully offline. CI examples now pin the version — an
    unpinned npx rugsnare floats to latest on every launch, the exact vector
    our own floating-version check flags in MCP configs. The native launcher
    checks rugsnare.com/latest-native.txt before writing a report
    (opt-out: -no-update-check).

  • Undeclared tool detection (new): the live proxy catches tools called by
    the agent that were never listed in tools/list (progressive-discovery servers).
    Blocked in enforce, one-time advisory in observe.

  • rugsnare diff now prints the human-readable WAS/NOW description text for
    description drift (COSMETIC and ANNOTATION) instead of bare hashes — you see
    the exact sentence the agent used to read and the one it reads now.

  • Scheduled checks (new, native launcher): rugsnare-skills install-schedule registers a logon check (Startup folder) and a daily
    check (Task Scheduler), no admin rights, no resident process — the binary
    runs and exits. Quiet mode (-quiet) stays silent when everything
    matches and opens the report only when something changed.

  • Cold-start audit (new, both CLIs): pinning is trust-on-first-use — it
    would bless a skill poisoned before RugSnare was installed. Every skill
    file's content is now scanned by the advisory engine (A01-A18) at scan
    and report time; pre-existing risks render as a separate "Already on
    your machine" section that explicitly says these are not update drift.

  • Security fixes (review 28): P0 canary leak via HTTP, P1 error scrubbing,
    committed verification key for CI, loud policies degradation, P2 guards.

  • Review 32 fixes: P0 os not imported — every rugsnare skills command
    crashed for real users without RUGSNARE_TEST_HOME set (tests masked it);
    file-pattern skill locations (.github/copilot-instructions.md,
    CONVENTIONS.md) were never discovered (readdir on a file → ENOTDIR);
    pure-deletion drift is now REVIEW, not SAFE (silently removed safety
    language must never read as safe); bare "token" no longer trips the
    credential pattern ("count the tokens" is LLM prose); compareVersions
    follows semver prerelease ordering (1.1.0-native.2 < 1.1.0).

Downloads (native skills scanner, no Node.js required): see the assets below — double-click, get a browser report. Works with Claude Code, Cursor, Windsurf, Continue, Cline, ZCode, Copilot, Codex, Amp, Kiro, OpenCode, Antigravity, Aider, Devin.

On-chain: artifact sha256 21b23f9dd5b64f81a3639775581726cdb56b502a580429b774428a8422e9d335 pinned to Base Mainnet (tx 0xa8ef…47ff); verify locally with npx rugsnare verify rugsnare-1.1.0.tgz --version 1.1.0 --chain base.

Web: the Runtime scan at rugsnare.com/#history runs rugsnare history in an ephemeral GitHub Actions sandbox — every result links to its public run log. The archive of all scans lives at rugsnare.com/scans.

v1.0.1 — CLI now defaults to Base Mainnet for --chain base

Choose a tag to compare

@Paraphern Paraphern released this 04 Oct 20:05

Fix release: the 1.0.0 npm tarball was built one commit before the Base Mainnet contract address was added to DEFAULT_CONTRACTS, so rugsnare verify --chain base failed with "No default ReleaseLog contract for chain base".

1.0.1 is built from the correct commit — --chain base works out of the box.

Verification

npx rugsnare verify rugsnare-1.0.1.tgz --version 1.0.1 --chain base
→ VERIFIED

On-chain pin: 0x8c3eb1…48a95
Contract: 0x78406c32…38B1e