home · demo · events · compare: remote-cross-session-context-leak

Remote Cross-Session Context Leak

MCP10MCP08

What just happened in your session

vulnerablecompare-vuln-remote-cross-session-context-leak2026-09-07T15:43:11.314823+00:00
side effect landed in var/telemetry.jsonl · canary CANARY_remote_cross_session_context_leak_b039bad15709c69408f80d8e
defendedcompare-def-remote-cross-session-context-leak2026-09-07T15:43:11.315045+00:00
blocked by session_isolation_policy · logged to var/telemetry.jsonl
Tool description that differed: run_demo

poisoned

Drive the canonical cross-session-context-leak scenario for this mode and return the DemoResult JSON.

sanitised

Drive the canonical cross-session-context-leak scenario for this mode and return the DemoResult JSON.

Vulnerable mode

violation_detected: truesecret_exfiltrated: true
✗ The attack succeeded
where it landed
var/telemetry.jsonl
cross session observation
From user
alice
Payload
CANARY_remote_cross_session_context_leak_e013387ceee65e885b2f74bd
cross session observation
From user
bob
Payload
CANARY_remote_cross_session_context_leak_b039bad15709c69408f80d8e
telemetry events for this run
session_leak_visible client:bobsession:alice/canonical-other allowed_by_vulnerable_mode
client:bob: observer 'bob' saw canary that belongs to 'alice'
session_leak_visible client:bobsession:alice/canonical-other allowed_by_vulnerable_mode
client:bob: observer 'bob' saw canary that belongs to 'alice'
session_leak_visible client:bobsession:bob/compare-def-remote-cross-session-context-leak allowed_by_vulnerable_mode
client:bob: observer 'bob' saw canary that belongs to 'bob'
session_leak_visible client:bobsession:alice/canonical-other allowed_by_vulnerable_mode
client:bob: observer 'bob' saw canary that belongs to 'alice'
session_leak_visible client:bobsession:bob/compare-def-remote-cross-session-context-leak allowed_by_vulnerable_mode
client:bob: observer 'bob' saw canary that belongs to 'bob'
session_leak_visible client:bobsession:alice/canonical-other allowed_by_vulnerable_mode
client:bob: observer 'bob' saw canary that belongs to 'alice'
session_leak_visible client:bobsession:bob/compare-def-remote-cross-session-context-leak allowed_by_vulnerable_mode
client:bob: observer 'bob' saw canary that belongs to 'bob'
session_leak_visible client:bobsession:alice/canonical-other allowed_by_vulnerable_mode
client:bob: observer 'bob' saw canary that belongs to 'alice'
session_leak_visible client:bobsession:bob/compare-def-remote-cross-session-context-leak allowed_by_vulnerable_mode
client:bob: observer 'bob' saw canary that belongs to 'bob'
session_leak_visible client:bobsession:alice/canonical-other allowed_by_vulnerable_mode
client:bob: observer 'bob' saw canary that belongs to 'alice'
session_leak_visible client:bobsession:bob/compare-def-remote-cross-session-context-leak allowed_by_vulnerable_mode
client:bob: observer 'bob' saw canary that belongs to 'bob'
session_leak_visible client:bobsession:alice/canonical-other allowed_by_vulnerable_mode
client:bob: observer 'bob' saw canary that belongs to 'alice'
session_leak_visible client:bobsession:bob/compare-def-remote-cross-session-context-leak allowed_by_vulnerable_mode
client:bob: observer 'bob' saw canary that belongs to 'bob'
session_leak_visible client:bobsession:alice/canonical-other allowed_by_vulnerable_mode
client:bob: observer 'bob' saw canary that belongs to 'alice'
session_leak_visible client:bobsession:bob/compare-def-remote-cross-session-context-leak allowed_by_vulnerable_mode
client:bob: observer 'bob' saw canary that belongs to 'bob'
Background
The vulnerable server stores per-call agent context in a single global dictionary instead of partitioning by Mcp-Session-Id. Session A writes a canary as a memory key; session B, talking to the same server, queries memory and reads back A's canary. There is no cross-tenant boundary at all - every session sees every other session's state.

Defended mode

violation_detected: truesecret_exfiltrated: falseblocked_by: session_isolation_policy
✓ The defense blocked the attack
where it landed
var/telemetry.jsonl
mitigations applied
  • session_isolation_policy
  • state_partitioned_by_user_and_session
  • per_partition_event_ids
session isolation block
From user
alice
Payload
[blocked]
Reason
observer's user id does not own this session id; lookup refused
session isolation block
From user
bob
Payload
[blocked]
Reason
observer's user id does not own this session id; lookup refused
telemetry events for this run
policy_decision policy.session_isolation_policysession:bob/compare-def-remote-cross-session-context-leak blocked
policy.session_isolation_policy: cross-session canary lookup refused; state is partitioned by (user_id, session_id)
policy_decision policy.session_isolation_policysession:bob/compare-def-remote-cross-session-context-leak blocked
policy.session_isolation_policy: cross-session canary lookup refused; state is partitioned by (user_id, session_id)
policy_decision policy.session_isolation_policysession:bob/compare-def-remote-cross-session-context-leak blocked
policy.session_isolation_policy: cross-session canary lookup refused; state is partitioned by (user_id, session_id)
policy_decision policy.session_isolation_policysession:bob/compare-def-remote-cross-session-context-leak blocked
policy.session_isolation_policy: cross-session canary lookup refused; state is partitioned by (user_id, session_id)
policy_decision policy.session_isolation_policysession:bob/compare-def-remote-cross-session-context-leak blocked
policy.session_isolation_policy: cross-session canary lookup refused; state is partitioned by (user_id, session_id)
policy_decision policy.session_isolation_policysession:bob/compare-def-remote-cross-session-context-leak blocked
policy.session_isolation_policy: cross-session canary lookup refused; state is partitioned by (user_id, session_id)
policy_decision policy.session_isolation_policysession:bob/compare-def-remote-cross-session-context-leak blocked
policy.session_isolation_policy: cross-session canary lookup refused; state is partitioned by (user_id, session_id)
Background
session_isolation_policy scopes every memory read and write to the active Mcp-Session-Id. Session B's query returns only its own keys; A's canary is invisible to anyone but A. The isolation event is recorded for both sessions.
Background on this attack class

Observer session sees other user canary vs. Partitioned store blocks cross session lookup

Developer view: raw outputs, tools/list, MCP Inspector
Vulnerable mount: http://mcp-sec.data.mayflower.tech/mcp/cross-session-context-leak/vulnerable/
Defended mount: http://mcp-sec.data.mayflower.tech/mcp/cross-session-context-leak/defended/
Open in MCP Inspector: run npx @modelcontextprotocol/inspector locally and paste either URL above as a Streamable HTTP server.
DemoResult: vulnerable
{
  "experiment": "remote-cross-session-context-leak",
  "mode": "vulnerable",
  "violation_detected": true,
  "secret_exfiltrated": true,
  "blocked_by": [],
  "events": [
    {
      "type": "cross_session_observation",
      "from_user": "alice",
      "payload": "CANARY_remote_cross_session_context_leak_e013387ceee65e885b2f74bd"
    },
    {
      "type": "cross_session_observation",
      "from_user": "bob",
      "payload": "CANARY_remote_cross_session_context_leak_b039bad15709c69408f80d8e"
    }
  ]
}
DemoResult: defended
{
  "experiment": "remote-cross-session-context-leak",
  "mode": "defended",
  "violation_detected": true,
  "secret_exfiltrated": false,
  "blocked_by": [
    "session_isolation_policy"
  ],
  "events": [
    {
      "type": "session_isolation_block",
      "from_user": "alice",
      "payload": "[blocked]",
      "reason": "observer's user id does not own this session id; lookup refused"
    },
    {
      "type": "session_isolation_block",
      "from_user": "bob",
      "payload": "[blocked]",
      "reason": "observer's user id does not own this session id; lookup refused"
    }
  ]
}
tools/list (vulnerable)
run_demo
description
Drive the canonical cross-session-context-leak scenario for this mode and return the DemoResult JSON.
inputSchema
{
  "properties": {
    "session_id": {
      "default": "mcp-vulnerable",
      "title": "Session Id",
      "type": "string"
    }
  },
  "title": "run_demoArguments",
  "type": "object"
}
tools/list (defended)
run_demo
description
Drive the canonical cross-session-context-leak scenario for this mode and return the DemoResult JSON.
inputSchema
{
  "properties": {
    "session_id": {
      "default": "mcp-defended",
      "title": "Session Id",
      "type": "string"
    }
  },
  "title": "run_demoArguments",
  "type": "object"
}
telemetry: vulnerable
[
  {
    "event_id": "evt_30e8b9fc6ff71f76",
    "ts": "2026-07-26T03:20:16.846809+00:00",
    "session_id": "compare-vuln-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "vulnerable",
    "event_type": "session_leak_visible",
    "severity": "warning",
    "message": "client:bob: observer 'bob' saw canary that belongs to 'alice'",
    "data": {
      "actor": "client:bob",
      "target": "session:alice/canonical-other",
      "policy_decision": "allowed_by_vulnerable_mode",
      "canary_id": "CANARY_remote_cross_session_context_leak_e013387ceee65e885b2f74bd",
      "artifact": null
    }
  },
  {
    "event_id": "evt_4f4d8b766294b3cb",
    "ts": "2026-08-12T15:00:43.878483+00:00",
    "session_id": "compare-vuln-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "vulnerable",
    "event_type": "session_leak_visible",
    "severity": "warning",
    "message": "client:bob: observer 'bob' saw canary that belongs to 'alice'",
    "data": {
      "actor": "client:bob",
      "target": "session:alice/canonical-other",
      "policy_decision": "allowed_by_vulnerable_mode",
      "canary_id": "CANARY_remote_cross_session_context_leak_e013387ceee65e885b2f74bd",
      "artifact": null
    }
  },
  {
    "event_id": "evt_168c2db0beeff019",
    "ts": "2026-08-12T15:00:43.878900+00:00",
    "session_id": "compare-vuln-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "vulnerable",
    "event_type": "session_leak_visible",
    "severity": "warning",
    "message": "client:bob: observer 'bob' saw canary that belongs to 'bob'",
    "data": {
      "actor": "client:bob",
      "target": "session:bob/compare-def-remote-cross-session-context-leak",
      "policy_decision": "allowed_by_vulnerable_mode",
      "canary_id": "CANARY_remote_cross_session_context_leak_b039bad15709c69408f80d8e",
      "artifact": null
    }
  },
  {
    "event_id": "evt_e31debc29108c3f4",
    "ts": "2026-08-19T08:56:25.515873+00:00",
    "session_id": "compare-vuln-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "vulnerable",
    "event_type": "session_leak_visible",
    "severity": "warning",
    "message": "client:bob: observer 'bob' saw canary that belongs to 'alice'",
    "data": {
      "actor": "client:bob",
      "target": "session:alice/canonical-other",
      "policy_decision": "allowed_by_vulnerable_mode",
      "canary_id": "CANARY_remote_cross_session_context_leak_e013387ceee65e885b2f74bd",
      "artifact": null
    }
  },
  {
    "event_id": "evt_e45067db4fed66e5",
    "ts": "2026-08-19T08:56:25.515951+00:00",
    "session_id": "compare-vuln-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "vulnerable",
    "event_type": "session_leak_visible",
    "severity": "warning",
    "message": "client:bob: observer 'bob' saw canary that belongs to 'bob'",
    "data": {
      "actor": "client:bob",
      "target": "session:bob/compare-def-remote-cross-session-context-leak",
      "policy_decision": "allowed_by_vulnerable_mode",
      "canary_id": "CANARY_remote_cross_session_context_leak_b039bad15709c69408f80d8e",
      "artifact": null
    }
  },
  {
    "event_id": "evt_57457923b11c262e",
    "ts": "2026-08-29T11:19:33.476329+00:00",
    "session_id": "compare-vuln-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "vulnerable",
    "event_type": "session_leak_visible",
    "severity": "warning",
    "message": "client:bob: observer 'bob' saw canary that belongs to 'alice'",
    "data": {
      "actor": "client:bob",
      "target": "session:alice/canonical-other",
      "policy_decision": "allowed_by_vulnerable_mode",
      "canary_id": "CANARY_remote_cross_session_context_leak_e013387ceee65e885b2f74bd",
      "artifact": null
    }
  },
  {
    "event_id": "evt_a733b26f450c032b",
    "ts": "2026-08-29T11:19:33.476677+00:00",
    "session_id": "compare-vuln-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "vulnerable",
    "event_type": "session_leak_visible",
    "severity": "warning",
    "message": "client:bob: observer 'bob' saw canary that belongs to 'bob'",
    "data": {
      "actor": "client:bob",
      "target": "session:bob/compare-def-remote-cross-session-context-leak",
      "policy_decision": "allowed_by_vulnerable_mode",
      "canary_id": "CANARY_remote_cross_session_context_leak_b039bad15709c69408f80d8e",
      "artifact": null
    }
  },
  {
    "event_id": "evt_268b07de3396c6b5",
    "ts": "2026-09-07T14:02:16.429193+00:00",
    "session_id": "compare-vuln-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "vulnerable",
    "event_type": "session_leak_visible",
    "severity": "warning",
    "message": "client:bob: observer 'bob' saw canary that belongs to 'alice'",
    "data": {
      "actor": "client:bob",
      "target": "session:alice/canonical-other",
      "policy_decision": "allowed_by_vulnerable_mode",
      "canary_id": "CANARY_remote_cross_session_context_leak_e013387ceee65e885b2f74bd",
      "artifact": null
    }
  },
  {
    "event_id": "evt_cb9e8513b8efe643",
    "ts": "2026-09-07T14:02:16.429281+00:00",
    "session_id": "compare-vuln-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "vulnerable",
    "event_type": "session_leak_visible",
    "severity": "warning",
    "message": "client:bob: observer 'bob' saw canary that belongs to 'bob'",
    "data": {
      "actor": "client:bob",
      "target": "session:bob/compare-def-remote-cross-session-context-leak",
      "policy_decision": "allowed_by_vulnerable_mode",
      "canary_id": "CANARY_remote_cross_session_context_leak_b039bad15709c69408f80d8e",
      "artifact": null
    }
  },
  {
    "event_id": "evt_e44a910f36007299",
    "ts": "2026-09-07T14:02:59.537145+00:00",
    "session_id": "compare-vuln-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "vulnerable",
    "event_type": "session_leak_visible",
    "severity": "warning",
    "message": "client:bob: observer 'bob' saw canary that belongs to 'alice'",
    "data": {
      "actor": "client:bob",
      "target": "session:alice/canonical-other",
      "policy_decision": "allowed_by_vulnerable_mode",
      "canary_id": "CANARY_remote_cross_session_context_leak_e013387ceee65e885b2f74bd",
      "artifact": null
    }
  },
  {
    "event_id": "evt_9a1ce74892158b44",
    "ts": "2026-09-07T14:02:59.537300+00:00",
    "session_id": "compare-vuln-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "vulnerable",
    "event_type": "session_leak_visible",
    "severity": "warning",
    "message": "client:bob: observer 'bob' saw canary that belongs to 'bob'",
    "data": {
      "actor": "client:bob",
      "target": "session:bob/compare-def-remote-cross-session-context-leak",
      "policy_decision": "allowed_by_vulnerable_mode",
      "canary_id": "CANARY_remote_cross_session_context_leak_b039bad15709c69408f80d8e",
      "artifact": null
    }
  },
  {
    "event_id": "evt_adc587e393248cd3",
    "ts": "2026-09-07T14:04:39.069587+00:00",
    "session_id": "compare-vuln-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "vulnerable",
    "event_type": "session_leak_visible",
    "severity": "warning",
    "message": "client:bob: observer 'bob' saw canary that belongs to 'alice'",
    "data": {
      "actor": "client:bob",
      "target": "session:alice/canonical-other",
      "policy_decision": "allowed_by_vulnerable_mode",
      "canary_id": "CANARY_remote_cross_session_context_leak_e013387ceee65e885b2f74bd",
      "artifact": null
    }
  },
  {
    "event_id": "evt_dc14b298c8156273",
    "ts": "2026-09-07T14:04:39.069902+00:00",
    "session_id": "compare-vuln-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "vulnerable",
    "event_type": "session_leak_visible",
    "severity": "warning",
    "message": "client:bob: observer 'bob' saw canary that belongs to 'bob'",
    "data": {
      "actor": "client:bob",
      "target": "session:bob/compare-def-remote-cross-session-context-leak",
      "policy_decision": "allowed_by_vulnerable_mode",
      "canary_id": "CANARY_remote_cross_session_context_leak_b039bad15709c69408f80d8e",
      "artifact": null
    }
  },
  {
    "event_id": "evt_13393089100ab484",
    "ts": "2026-09-07T15:43:11.314537+00:00",
    "session_id": "compare-vuln-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "vulnerable",
    "event_type": "session_leak_visible",
    "severity": "warning",
    "message": "client:bob: observer 'bob' saw canary that belongs to 'alice'",
    "data": {
      "actor": "client:bob",
      "target": "session:alice/canonical-other",
      "policy_decision": "allowed_by_vulnerable_mode",
      "canary_id": "CANARY_remote_cross_session_context_leak_e013387ceee65e885b2f74bd",
      "artifact": null
    }
  },
  {
    "event_id": "evt_6714fb020f8f0b41",
    "ts": "2026-09-07T15:43:11.314823+00:00",
    "session_id": "compare-vuln-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "vulnerable",
    "event_type": "session_leak_visible",
    "severity": "warning",
    "message": "client:bob: observer 'bob' saw canary that belongs to 'bob'",
    "data": {
      "actor": "client:bob",
      "target": "session:bob/compare-def-remote-cross-session-context-leak",
      "policy_decision": "allowed_by_vulnerable_mode",
      "canary_id": "CANARY_remote_cross_session_context_leak_b039bad15709c69408f80d8e",
      "artifact": null
    }
  }
]
telemetry: defended
[
  {
    "event_id": "evt_c90c2f59e6b63163",
    "ts": "2026-07-26T03:20:16.847080+00:00",
    "session_id": "compare-def-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "defended",
    "event_type": "policy_decision",
    "severity": "warning",
    "message": "policy.session_isolation_policy: cross-session canary lookup refused; state is partitioned by (user_id, session_id)",
    "data": {
      "actor": "policy.session_isolation_policy",
      "target": "session:bob/compare-def-remote-cross-session-context-leak",
      "policy_decision": "blocked",
      "canary_id": null,
      "artifact": null,
      "reason": "cross-session canary lookup refused; state is partitioned by (user_id, session_id)"
    }
  },
  {
    "event_id": "evt_278f6c5792e49d6f",
    "ts": "2026-08-19T08:56:25.516018+00:00",
    "session_id": "compare-def-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "defended",
    "event_type": "policy_decision",
    "severity": "warning",
    "message": "policy.session_isolation_policy: cross-session canary lookup refused; state is partitioned by (user_id, session_id)",
    "data": {
      "actor": "policy.session_isolation_policy",
      "target": "session:bob/compare-def-remote-cross-session-context-leak",
      "policy_decision": "blocked",
      "canary_id": null,
      "artifact": null,
      "reason": "cross-session canary lookup refused; state is partitioned by (user_id, session_id)"
    }
  },
  {
    "event_id": "evt_1beb35f933d9af61",
    "ts": "2026-08-29T11:19:33.476992+00:00",
    "session_id": "compare-def-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "defended",
    "event_type": "policy_decision",
    "severity": "warning",
    "message": "policy.session_isolation_policy: cross-session canary lookup refused; state is partitioned by (user_id, session_id)",
    "data": {
      "actor": "policy.session_isolation_policy",
      "target": "session:bob/compare-def-remote-cross-session-context-leak",
      "policy_decision": "blocked",
      "canary_id": null,
      "artifact": null,
      "reason": "cross-session canary lookup refused; state is partitioned by (user_id, session_id)"
    }
  },
  {
    "event_id": "evt_c11b1ae012108fc2",
    "ts": "2026-09-07T14:02:16.429354+00:00",
    "session_id": "compare-def-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "defended",
    "event_type": "policy_decision",
    "severity": "warning",
    "message": "policy.session_isolation_policy: cross-session canary lookup refused; state is partitioned by (user_id, session_id)",
    "data": {
      "actor": "policy.session_isolation_policy",
      "target": "session:bob/compare-def-remote-cross-session-context-leak",
      "policy_decision": "blocked",
      "canary_id": null,
      "artifact": null,
      "reason": "cross-session canary lookup refused; state is partitioned by (user_id, session_id)"
    }
  },
  {
    "event_id": "evt_31ae95771123c84f",
    "ts": "2026-09-07T14:02:59.537397+00:00",
    "session_id": "compare-def-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "defended",
    "event_type": "policy_decision",
    "severity": "warning",
    "message": "policy.session_isolation_policy: cross-session canary lookup refused; state is partitioned by (user_id, session_id)",
    "data": {
      "actor": "policy.session_isolation_policy",
      "target": "session:bob/compare-def-remote-cross-session-context-leak",
      "policy_decision": "blocked",
      "canary_id": null,
      "artifact": null,
      "reason": "cross-session canary lookup refused; state is partitioned by (user_id, session_id)"
    }
  },
  {
    "event_id": "evt_288dc7d04cdb8c07",
    "ts": "2026-09-07T14:04:39.070108+00:00",
    "session_id": "compare-def-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "defended",
    "event_type": "policy_decision",
    "severity": "warning",
    "message": "policy.session_isolation_policy: cross-session canary lookup refused; state is partitioned by (user_id, session_id)",
    "data": {
      "actor": "policy.session_isolation_policy",
      "target": "session:bob/compare-def-remote-cross-session-context-leak",
      "policy_decision": "blocked",
      "canary_id": null,
      "artifact": null,
      "reason": "cross-session canary lookup refused; state is partitioned by (user_id, session_id)"
    }
  },
  {
    "event_id": "evt_09bebf5b682f1ec8",
    "ts": "2026-09-07T15:43:11.315045+00:00",
    "session_id": "compare-def-remote-cross-session-context-leak",
    "experiment": "remote-cross-session-context-leak",
    "mode": "defended",
    "event_type": "policy_decision",
    "severity": "warning",
    "message": "policy.session_isolation_policy: cross-session canary lookup refused; state is partitioned by (user_id, session_id)",
    "data": {
      "actor": "policy.session_isolation_policy",
      "target": "session:bob/compare-def-remote-cross-session-context-leak",
      "policy_decision": "blocked",
      "canary_id": null,
      "artifact": null,
      "reason": "cross-session canary lookup refused; state is partitioned by (user_id, session_id)"
    }
  }
]