Bash sandbox filesystem isolation does not confine on Linux-in-Docker — default allow-list AND deny-list both bypassed (atomic repro; corroborates #32226, #29048)

Status Closed — not planned
Reported on v2.1.224
Maintainer reply None cached
Activity 1 comment · opened Aug 12, 2026 · closed Aug 12, 2026

Corroboration for #32226 / #29048: Bash-sandbox filesystem isolation does not confine on Linux-in-Docker (default allow-list AND deny-list), with an atomic namespace-verified reproduction

Not a new report. This corroborates and extends:

  • #32226 "sandbox denyRead seems ineffective" (closed not planned)
  • #29048 in-process Write/Edit bypass bwrap; permission-rule-only gating

Versions: 2.1.224 and 2.1.227 (native binary). Host macOS/OrbStack 29.4.0;
container Ubuntu 26.04, bubblewrap + socat present.

What's new vs the existing issues

The existing reports show deny-list carve-outs being ineffective. This adds
that the default allow-list confinement also does not hold: a Bash
subprocess writes outside cwd and the session temp dir and the file lands on
the real filesystem — while the command is provably running inside the sandbox.

Atomic, outside-verified reproduction

One sandboxed command reports its own mount namespace and writes outside cwd:

NS=mnt:[…621]  WROTE=True        # the sandboxed command
container mnt: mnt:[…626]        # differs → the command IS sandbox-wrapped
/home/dev/ATOMIC.txt on disk     # a write outside cwd+temp landed for real
  • Distinct mount namespace ⇒ the command is genuinely sandboxed (also

failIfUnavailable: true, so no silent unsandboxed fallback).

  • Real on-disk existence, checked from a separate docker exec ⇒ not a

shadow/masked write.

Both simultaneously ⇒ the sandbox runs but does not confine filesystem access.

Deny-list arm (matches #32226): a denyWrite-listed pre-existing file, hashed
before/after a sandboxed append — hash changes, marker present in the real file.

Scope of reproduction

2.1.224 and 2.1.227; literal / glob / ${containerWorkspaceFolder} shapes;
managed, user, and ~/.srt-settings.json scopes; privileged and unprivileged
(seccomp userns) containers; managed floor present or hidden.

Secondary findings (unprivileged-container setup friction)

  1. enableWeakerNestedSandbox: true appears inert on 2.1.224/2.1.227: set in

all three scopes, bwrap still attempts a fresh /proc and fails
("Can't mount proc on /newroot/proc"). Workaround that works:
--security-opt systempaths=unconfined.

  1. Sandbox fails until a bind target exists at /home/.mcp.json

("bwrap: Can't create file at /home/.mcp.json") — /home is root-owned;
pre-creating the file unblocks it.

Ask

  • Reopen or cross-link #32226 with this default-allow-list evidence.
  • A schema-valid-but-inert sandbox.filesystem config should WARN at startup,

not pass silently — this is what made the gap invisible for so long.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗