compare-vuln-remote-registry-rug-pull2026-09-07T15:43:11.479359+00:00/app/sandbox/effects/registry-rug-pull-compare-vuln-remote-registry-rug-pull.json · canary CANARY_remote_registry_rug_pull_18654df6bd0199e8c2a819e8compare-def-remote-registry-rug-pull2026-09-07T15:43:11.479591+00:00registry_pinning_policy · logged to var/telemetry.jsonlrun_demosandbox/effects/registry-rug-pull-<session>.json1.0.02.0.0{3 keys}[2 items]registry.drift-mock.example-server → drift-mock.example-server@2.0.0 allowed_by_vulnerable_moderegistry.drift-mock.example-server → drift-mock.example-server@2.0.0 allowed_by_vulnerable_moderegistry.drift-mock.example-server → drift-mock.example-server@2.0.0 allowed_by_vulnerable_moderegistry.drift-mock.example-server → drift-mock.example-server@2.0.0 allowed_by_vulnerable_moderegistry.drift-mock.example-server → drift-mock.example-server@2.0.0 allowed_by_vulnerable_moderegistry.drift-mock.example-server → drift-mock.example-server@2.0.0 allowed_by_vulnerable_moderegistry.drift-mock.example-server → drift-mock.example-server@2.0.0 allowed_by_vulnerable_modevar/telemetry.jsonlregistry_pinning_policyregistry_pinning_policypermission_delta_reviewtool_fingerprint_pinning1.0.02.0.0{3 keys}[2 items]ask the user to re-approve the new server manifest before activating the new versionpolicy.registry_pinning_policy → drift-mock.example-server@2.0.0 blockedpolicy.registry_pinning_policy → drift-mock.example-server@2.0.0 blockedpolicy.registry_pinning_policy → drift-mock.example-server@2.0.0 blockedpolicy.registry_pinning_policy → drift-mock.example-server@2.0.0 blockedpolicy.registry_pinning_policy → drift-mock.example-server@2.0.0 blockedpolicy.registry_pinning_policy → drift-mock.example-server@2.0.0 blockedpolicy.registry_pinning_policy → drift-mock.example-server@2.0.0 blockedSafe remote registry-rug-pull demo. The demo simulates a supply-chain attack on an MCP server registry: v1 of ``drift-mock.example-server`` is benign. v2 keeps the same server id and the same tool name but adds two permissions (``read:contacts``, ``send:message``), grows the input schema and ships a poisoned description. The registry is read entirely from local YAML fixtures - no network, no third-party install. Modes: - ``vulnerable``: activates ``latest`` (= v2) without consulting the user. An artefact is written to ``sandbox/effects/registry-rug-pull-<session>.json`` with the resolved version, the permission delta, and the per-tool hash diff so a reviewer can see exactly what changed. - ``defended``: enforces a user-pinned version and refuses to activate whenever the registry returns a different version, a non-empty permission delta, or a tool fingerprint drift. ``record_blocked_attempt`` emits a structured block event with the diff.
http://mcp-sec.data.mayflower.tech/mcp/registry-rug-pull/vulnerable/http://mcp-sec.data.mayflower.tech/mcp/registry-rug-pull/defended/npx @modelcontextprotocol/inspector locally and paste either URL above as a Streamable HTTP server.{
"experiment": "remote-registry-rug-pull",
"mode": "vulnerable",
"violation_detected": true,
"secret_exfiltrated": false,
"blocked_by": [],
"events": [
{
"type": "registry_diff",
"before_version": "1.0.0",
"after_version": "2.0.0",
"permission_delta": {
"added": [
"read:contacts",
"send:message"
],
"removed": [],
"broadened": []
},
"tool_hash_changes": [
{
"tool": "message.send",
"kind": "added",
"description_hash_after": "e49dd2f80325997d00a1c9234ca29b5896fce708d578a4fa009897d6bed2e41b",
"schema_hash_after": "6db7da64b9a1c7162f246c6b6d41b19e9787e61a2f196e16808b74c8f074aa8f"
},
{
"tool": "profile.get",
"kind": "changed",
"description_hash_before": "ecb5d2f40cde2481941758ede9f16b7900c5c09f20e31d0231980c9636d02dc0",
"description_hash_after": "01f72e184d911900f9c6ab65cb949ad5cfb9486ca7b60a0488dc205e92d6fd97",
"schema_hash_before": "c8a1ac469a826ea3547ac220c7bbfdcd6b58080d4ec596ff2a0149c5ccb9b699",
"schema_hash_after": "bb9b00266367d50a53ce621c9319329fae68d503c0107e32edbd80710463f630"
}
]
}
]
}{
"experiment": "remote-registry-rug-pull",
"mode": "defended",
"violation_detected": true,
"secret_exfiltrated": false,
"blocked_by": [
"registry_pinning_policy"
],
"events": [
{
"type": "registry_diff",
"before_version": "1.0.0",
"after_version": "2.0.0",
"permission_delta": {
"added": [
"read:contacts",
"send:message"
],
"removed": [],
"broadened": []
},
"tool_hash_changes": [
{
"tool": "message.send",
"kind": "added",
"description_hash_after": "e49dd2f80325997d00a1c9234ca29b5896fce708d578a4fa009897d6bed2e41b",
"schema_hash_after": "6db7da64b9a1c7162f246c6b6d41b19e9787e61a2f196e16808b74c8f074aa8f"
},
{
"tool": "profile.get",
"kind": "changed",
"description_hash_before": "ecb5d2f40cde2481941758ede9f16b7900c5c09f20e31d0231980c9636d02dc0",
"description_hash_after": "01f72e184d911900f9c6ab65cb949ad5cfb9486ca7b60a0488dc205e92d6fd97",
"schema_hash_before": "c8a1ac469a826ea3547ac220c7bbfdcd6b58080d4ec596ff2a0149c5ccb9b699",
"schema_hash_after": "bb9b00266367d50a53ce621c9319329fae68d503c0107e32edbd80710463f630"
}
],
"recommendation": "ask the user to re-approve the new server manifest before activating the new version"
}
]
}Run the canonical scenario and return DemoResult.
{
"properties": {
"session_id": {
"default": "mcp-vulnerable",
"title": "Session Id",
"type": "string"
}
},
"title": "run_demoArguments",
"type": "object"
}Run the canonical scenario and return DemoResult.
{
"properties": {
"session_id": {
"default": "mcp-defended",
"title": "Session Id",
"type": "string"
}
},
"title": "run_demoArguments",
"type": "object"
}[
{
"event_id": "evt_57dfd200436f5d27",
"ts": "2026-07-26T03:20:16.476729+00:00",
"session_id": "compare-vuln-remote-registry-rug-pull",
"experiment": "remote-registry-rug-pull",
"mode": "vulnerable",
"event_type": "permission_change_applied",
"severity": "info",
"message": "registry.drift-mock.example-server: silently activated 2.0.0; permissions added: ['read:contacts', 'send:message']",
"data": {
"actor": "registry.drift-mock.example-server",
"target": "drift-mock.example-server@2.0.0",
"policy_decision": "allowed_by_vulnerable_mode",
"canary_id": "CANARY_remote_registry_rug_pull_18654df6bd0199e8c2a819e8",
"artifact": "/app/sandbox/effects/registry-rug-pull-compare-vuln-remote-registry-rug-pull.json"
}
},
{
"event_id": "evt_8a407a2a25d9a18e",
"ts": "2026-08-19T08:56:24.817706+00:00",
"session_id": "compare-vuln-remote-registry-rug-pull",
"experiment": "remote-registry-rug-pull",
"mode": "vulnerable",
"event_type": "permission_change_applied",
"severity": "info",
"message": "registry.drift-mock.example-server: silently activated 2.0.0; permissions added: ['read:contacts', 'send:message']",
"data": {
"actor": "registry.drift-mock.example-server",
"target": "drift-mock.example-server@2.0.0",
"policy_decision": "allowed_by_vulnerable_mode",
"canary_id": "CANARY_remote_registry_rug_pull_18654df6bd0199e8c2a819e8",
"artifact": "/app/sandbox/effects/registry-rug-pull-compare-vuln-remote-registry-rug-pull.json"
}
},
{
"event_id": "evt_d743cc588234fc5a",
"ts": "2026-08-29T11:19:32.011788+00:00",
"session_id": "compare-vuln-remote-registry-rug-pull",
"experiment": "remote-registry-rug-pull",
"mode": "vulnerable",
"event_type": "permission_change_applied",
"severity": "info",
"message": "registry.drift-mock.example-server: silently activated 2.0.0; permissions added: ['read:contacts', 'send:message']",
"data": {
"actor": "registry.drift-mock.example-server",
"target": "drift-mock.example-server@2.0.0",
"policy_decision": "allowed_by_vulnerable_mode",
"canary_id": "CANARY_remote_registry_rug_pull_18654df6bd0199e8c2a819e8",
"artifact": "/app/sandbox/effects/registry-rug-pull-compare-vuln-remote-registry-rug-pull.json"
}
},
{
"event_id": "evt_22d881b44f7f88dc",
"ts": "2026-09-07T14:02:16.174446+00:00",
"session_id": "compare-vuln-remote-registry-rug-pull",
"experiment": "remote-registry-rug-pull",
"mode": "vulnerable",
"event_type": "permission_change_applied",
"severity": "info",
"message": "registry.drift-mock.example-server: silently activated 2.0.0; permissions added: ['read:contacts', 'send:message']",
"data": {
"actor": "registry.drift-mock.example-server",
"target": "drift-mock.example-server@2.0.0",
"policy_decision": "allowed_by_vulnerable_mode",
"canary_id": "CANARY_remote_registry_rug_pull_18654df6bd0199e8c2a819e8",
"artifact": "/app/sandbox/effects/registry-rug-pull-compare-vuln-remote-registry-rug-pull.json"
}
},
{
"event_id": "evt_ad9b0942d2d4bbd7",
"ts": "2026-09-07T14:02:59.185601+00:00",
"session_id": "compare-vuln-remote-registry-rug-pull",
"experiment": "remote-registry-rug-pull",
"mode": "vulnerable",
"event_type": "permission_change_applied",
"severity": "info",
"message": "registry.drift-mock.example-server: silently activated 2.0.0; permissions added: ['read:contacts', 'send:message']",
"data": {
"actor": "registry.drift-mock.example-server",
"target": "drift-mock.example-server@2.0.0",
"policy_decision": "allowed_by_vulnerable_mode",
"canary_id": "CANARY_remote_registry_rug_pull_18654df6bd0199e8c2a819e8",
"artifact": "/app/sandbox/effects/registry-rug-pull-compare-vuln-remote-registry-rug-pull.json"
}
},
{
"event_id": "evt_01ddd586ccf7d258",
"ts": "2026-09-07T14:04:38.691690+00:00",
"session_id": "compare-vuln-remote-registry-rug-pull",
"experiment": "remote-registry-rug-pull",
"mode": "vulnerable",
"event_type": "permission_change_applied",
"severity": "info",
"message": "registry.drift-mock.example-server: silently activated 2.0.0; permissions added: ['read:contacts', 'send:message']",
"data": {
"actor": "registry.drift-mock.example-server",
"target": "drift-mock.example-server@2.0.0",
"policy_decision": "allowed_by_vulnerable_mode",
"canary_id": "CANARY_remote_registry_rug_pull_18654df6bd0199e8c2a819e8",
"artifact": "/app/sandbox/effects/registry-rug-pull-compare-vuln-remote-registry-rug-pull.json"
}
},
{
"event_id": "evt_6cb62a8eac637463",
"ts": "2026-09-07T15:43:11.479359+00:00",
"session_id": "compare-vuln-remote-registry-rug-pull",
"experiment": "remote-registry-rug-pull",
"mode": "vulnerable",
"event_type": "permission_change_applied",
"severity": "info",
"message": "registry.drift-mock.example-server: silently activated 2.0.0; permissions added: ['read:contacts', 'send:message']",
"data": {
"actor": "registry.drift-mock.example-server",
"target": "drift-mock.example-server@2.0.0",
"policy_decision": "allowed_by_vulnerable_mode",
"canary_id": "CANARY_remote_registry_rug_pull_18654df6bd0199e8c2a819e8",
"artifact": "/app/sandbox/effects/registry-rug-pull-compare-vuln-remote-registry-rug-pull.json"
}
}
][
{
"event_id": "evt_72e8f5e49cf1770e",
"ts": "2026-07-26T03:20:16.477057+00:00",
"session_id": "compare-def-remote-registry-rug-pull",
"experiment": "remote-registry-rug-pull",
"mode": "defended",
"event_type": "policy_decision",
"severity": "warning",
"message": "policy.registry_pinning_policy: registry drift: pinned=None latest='2.0.0'; permissions added=['read:contacts', 'send:message']; tool changes=['message.send', 'profile.get']",
"data": {
"actor": "policy.registry_pinning_policy",
"target": "drift-mock.example-server@2.0.0",
"policy_decision": "blocked",
"canary_id": null,
"artifact": null,
"reason": "registry drift: pinned=None latest='2.0.0'; permissions added=['read:contacts', 'send:message']; tool changes=['message.send', 'profile.get']"
}
},
{
"event_id": "evt_87d44fc159385f7c",
"ts": "2026-08-19T08:56:24.817953+00:00",
"session_id": "compare-def-remote-registry-rug-pull",
"experiment": "remote-registry-rug-pull",
"mode": "defended",
"event_type": "policy_decision",
"severity": "warning",
"message": "policy.registry_pinning_policy: registry drift: pinned=None latest='2.0.0'; permissions added=['read:contacts', 'send:message']; tool changes=['message.send', 'profile.get']",
"data": {
"actor": "policy.registry_pinning_policy",
"target": "drift-mock.example-server@2.0.0",
"policy_decision": "blocked",
"canary_id": null,
"artifact": null,
"reason": "registry drift: pinned=None latest='2.0.0'; permissions added=['read:contacts', 'send:message']; tool changes=['message.send', 'profile.get']"
}
},
{
"event_id": "evt_7c810bc54b360174",
"ts": "2026-08-29T11:19:32.011936+00:00",
"session_id": "compare-def-remote-registry-rug-pull",
"experiment": "remote-registry-rug-pull",
"mode": "defended",
"event_type": "policy_decision",
"severity": "warning",
"message": "policy.registry_pinning_policy: registry drift: pinned=None latest='2.0.0'; permissions added=['read:contacts', 'send:message']; tool changes=['message.send', 'profile.get']",
"data": {
"actor": "policy.registry_pinning_policy",
"target": "drift-mock.example-server@2.0.0",
"policy_decision": "blocked",
"canary_id": null,
"artifact": null,
"reason": "registry drift: pinned=None latest='2.0.0'; permissions added=['read:contacts', 'send:message']; tool changes=['message.send', 'profile.get']"
}
},
{
"event_id": "evt_5c9926f79ef2fba4",
"ts": "2026-09-07T14:02:16.174644+00:00",
"session_id": "compare-def-remote-registry-rug-pull",
"experiment": "remote-registry-rug-pull",
"mode": "defended",
"event_type": "policy_decision",
"severity": "warning",
"message": "policy.registry_pinning_policy: registry drift: pinned=None latest='2.0.0'; permissions added=['read:contacts', 'send:message']; tool changes=['message.send', 'profile.get']",
"data": {
"actor": "policy.registry_pinning_policy",
"target": "drift-mock.example-server@2.0.0",
"policy_decision": "blocked",
"canary_id": null,
"artifact": null,
"reason": "registry drift: pinned=None latest='2.0.0'; permissions added=['read:contacts', 'send:message']; tool changes=['message.send', 'profile.get']"
}
},
{
"event_id": "evt_b9d98f31b34f95db",
"ts": "2026-09-07T14:02:59.185923+00:00",
"session_id": "compare-def-remote-registry-rug-pull",
"experiment": "remote-registry-rug-pull",
"mode": "defended",
"event_type": "policy_decision",
"severity": "warning",
"message": "policy.registry_pinning_policy: registry drift: pinned=None latest='2.0.0'; permissions added=['read:contacts', 'send:message']; tool changes=['message.send', 'profile.get']",
"data": {
"actor": "policy.registry_pinning_policy",
"target": "drift-mock.example-server@2.0.0",
"policy_decision": "blocked",
"canary_id": null,
"artifact": null,
"reason": "registry drift: pinned=None latest='2.0.0'; permissions added=['read:contacts', 'send:message']; tool changes=['message.send', 'profile.get']"
}
},
{
"event_id": "evt_806236fe557b08d9",
"ts": "2026-09-07T14:04:38.691839+00:00",
"session_id": "compare-def-remote-registry-rug-pull",
"experiment": "remote-registry-rug-pull",
"mode": "defended",
"event_type": "policy_decision",
"severity": "warning",
"message": "policy.registry_pinning_policy: registry drift: pinned=None latest='2.0.0'; permissions added=['read:contacts', 'send:message']; tool changes=['message.send', 'profile.get']",
"data": {
"actor": "policy.registry_pinning_policy",
"target": "drift-mock.example-server@2.0.0",
"policy_decision": "blocked",
"canary_id": null,
"artifact": null,
"reason": "registry drift: pinned=None latest='2.0.0'; permissions added=['read:contacts', 'send:message']; tool changes=['message.send', 'profile.get']"
}
},
{
"event_id": "evt_1707f94798976aff",
"ts": "2026-09-07T15:43:11.479591+00:00",
"session_id": "compare-def-remote-registry-rug-pull",
"experiment": "remote-registry-rug-pull",
"mode": "defended",
"event_type": "policy_decision",
"severity": "warning",
"message": "policy.registry_pinning_policy: registry drift: pinned=None latest='2.0.0'; permissions added=['read:contacts', 'send:message']; tool changes=['message.send', 'profile.get']",
"data": {
"actor": "policy.registry_pinning_policy",
"target": "drift-mock.example-server@2.0.0",
"policy_decision": "blocked",
"canary_id": null,
"artifact": null,
"reason": "registry drift: pinned=None latest='2.0.0'; permissions added=['read:contacts', 'send:message']; tool changes=['message.send', 'profile.get']"
}
}
]