compare-vuln-remote-filesystem-sandbox-escape2026-11-06T13:27:04.560610+00:00/app/sandbox/outside/canary.txt · canary CANARY_remote_filesystem_sandbox_escape_ac222c9058b8f6be2334e03acompare-def-remote-filesystem-sandbox-escape2026-11-06T13:27:04.561289+00:00filesystem_resolved_path_policy · logged to var/telemetry.jsonlread_filevar/telemetry.jsonl../outside/canary.txt/app/sandbox/allowed/app/sandbox/outside/canary.txtTruevulnerable-fs-validator → /app/sandbox/outside/canary.txt allowed_by_vulnerable_modevulnerable-fs-validator → /app/sandbox/outside/canary.txt allowed_by_vulnerable_modevar/telemetry.jsonlfilesystem_resolved_path_policy../outside/canary.txt/app/sandbox/allowedFalseparent traversal refusedpolicy.filesystem_resolved_path_policy → ../outside/canary.txt blockedpolicy.filesystem_resolved_path_policy → ../outside/canary.txt blockedSafe filesystem MCP sandbox-escape demo. A deliberately weak path validator (prefix-only string check) lets a crafted path read a canary file that lives outside the allowed root, *but* still inside the demo's overall sandbox (so no real files are ever read). The defended validator resolves the canonical path and checks containment via ``Path.relative_to``.
http://mcp-sec.data.mayflower.tech/mcp/filesystem-sandbox-escape/vulnerable/http://mcp-sec.data.mayflower.tech/mcp/filesystem-sandbox-escape/defended/npx @modelcontextprotocol/inspector locally and paste either URL above as a Streamable HTTP server.{
"experiment": "remote-filesystem-sandbox-escape",
"mode": "vulnerable",
"violation_detected": true,
"secret_exfiltrated": true,
"blocked_by": [],
"events": [
{
"type": "fs_decision",
"requested_path": "../outside/canary.txt",
"allowed_root": "/app/sandbox/allowed",
"resolved_path": "/app/sandbox/outside/canary.txt",
"would_have_read": true
}
]
}{
"experiment": "remote-filesystem-sandbox-escape",
"mode": "defended",
"violation_detected": true,
"secret_exfiltrated": false,
"blocked_by": [
"filesystem_resolved_path_policy"
],
"events": [
{
"type": "fs_decision",
"requested_path": "../outside/canary.txt",
"allowed_root": "/app/sandbox/allowed",
"would_have_read": false,
"reason": "parent traversal refused"
}
]
}Read a file relative to the allowed sandbox root. Vulnerable mode trusts string-prefix containment; defended mode runs Path.resolve + relative_to.
{
"properties": {
"relative_path": {
"title": "Relative Path",
"type": "string"
},
"session_id": {
"default": "mcp-vulnerable",
"title": "Session Id",
"type": "string"
}
},
"required": [
"relative_path"
],
"title": "read_fileArguments",
"type": "object"
}Run the canonical scenario and return DemoResult.
{
"properties": {
"session_id": {
"default": "mcp-vulnerable",
"title": "Session Id",
"type": "string"
}
},
"title": "run_demoArguments",
"type": "object"
}Read a file relative to the allowed sandbox root. Vulnerable mode trusts string-prefix containment; defended mode runs Path.resolve + relative_to.
{
"properties": {
"relative_path": {
"title": "Relative Path",
"type": "string"
},
"session_id": {
"default": "mcp-defended",
"title": "Session Id",
"type": "string"
}
},
"required": [
"relative_path"
],
"title": "read_fileArguments",
"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_eb22625b1b463f6d",
"ts": "2026-11-06T13:11:03.608504+00:00",
"session_id": "compare-vuln-remote-filesystem-sandbox-escape",
"experiment": "remote-filesystem-sandbox-escape",
"mode": "vulnerable",
"event_type": "session_leak_visible",
"severity": "warning",
"message": "vulnerable-fs-validator: weak path validator served '../outside/canary.txt' from outside the allowed root",
"data": {
"actor": "vulnerable-fs-validator",
"target": "/app/sandbox/outside/canary.txt",
"policy_decision": "allowed_by_vulnerable_mode",
"canary_id": "CANARY_remote_filesystem_sandbox_escape_ac222c9058b8f6be2334e03a",
"artifact": "/app/sandbox/outside/canary.txt",
"requested_path": "../outside/canary.txt",
"allowed_root": "/app/sandbox/allowed",
"resolved_path": "/app/sandbox/outside/canary.txt"
}
},
{
"event_id": "evt_33fc01539edb60e2",
"ts": "2026-11-06T13:27:04.560610+00:00",
"session_id": "compare-vuln-remote-filesystem-sandbox-escape",
"experiment": "remote-filesystem-sandbox-escape",
"mode": "vulnerable",
"event_type": "session_leak_visible",
"severity": "warning",
"message": "vulnerable-fs-validator: weak path validator served '../outside/canary.txt' from outside the allowed root",
"data": {
"actor": "vulnerable-fs-validator",
"target": "/app/sandbox/outside/canary.txt",
"policy_decision": "allowed_by_vulnerable_mode",
"canary_id": "CANARY_remote_filesystem_sandbox_escape_ac222c9058b8f6be2334e03a",
"artifact": "/app/sandbox/outside/canary.txt",
"requested_path": "../outside/canary.txt",
"allowed_root": "/app/sandbox/allowed",
"resolved_path": "/app/sandbox/outside/canary.txt"
}
}
][
{
"event_id": "evt_1876025acc97adc3",
"ts": "2026-11-06T13:11:03.608866+00:00",
"session_id": "compare-def-remote-filesystem-sandbox-escape",
"experiment": "remote-filesystem-sandbox-escape",
"mode": "defended",
"event_type": "policy_decision",
"severity": "warning",
"message": "policy.filesystem_resolved_path_policy: parent traversal refused",
"data": {
"actor": "policy.filesystem_resolved_path_policy",
"target": "../outside/canary.txt",
"policy_decision": "blocked",
"canary_id": null,
"artifact": null,
"reason": "parent traversal refused"
}
},
{
"event_id": "evt_c1360aa91bab8835",
"ts": "2026-11-06T13:27:04.561289+00:00",
"session_id": "compare-def-remote-filesystem-sandbox-escape",
"experiment": "remote-filesystem-sandbox-escape",
"mode": "defended",
"event_type": "policy_decision",
"severity": "warning",
"message": "policy.filesystem_resolved_path_policy: parent traversal refused",
"data": {
"actor": "policy.filesystem_resolved_path_policy",
"target": "../outside/canary.txt",
"policy_decision": "blocked",
"canary_id": null,
"artifact": null,
"reason": "parent traversal refused"
}
}
]