Skip to content

getAvailableToolsPolicy grants read access to the whole system drive on BaseContainer when pwsh is on PATH #1455

Description

@PierrunoYT

Relevant area(s)

Windows

Brief description of your issue

When PowerShell 7 (pwsh.exe) is on PATH, getAvailableToolsPolicy adds the drive root C:\ to readonlyPaths. This is documented ("so that interactive PowerShell sessions work correctly inside the container"). But on a BaseContainer host the grant covers the whole subtree, so a sandbox built from the README's recommended baseline (getAvailableToolsPolicy + getTemporaryFilesPolicy) can read every file the user can: the user profile, %USERPROFILE%\.aws, .ssh, browser profiles, other projects. Most developer machines with PowerShell 7 installed get this policy, and nothing in the result or the logs signals that the sandbox no longer limits reads.

Steps to reproduce

Windows 11 25H2, build 26200.9457. getPlatformSupport() reports isolationTier: "base-container". @microsoft/mxc-sdk 0.9.0 and 1.0.0 (policy.filesystem.getAvailableToolsPolicy from @microsoft/mxc-sdk/v1), Node 24.21.0.

  1. The helper's result depends only on whether PowerShell 7 is on PATH:
import { delimiter, join } from 'node:path';
import { policy } from '@microsoft/mxc-sdk/v1';

const tools = policy.filesystem.getAvailableToolsPolicy;
const sys = join(process.env.SystemRoot, 'System32');
const node = join(process.env.ProgramFiles, 'nodejs');
const pwsh = join(process.env.ProgramFiles, 'PowerShell', '7');
const roots = (t) => t.readonlyPaths.filter((p) => p.length <= 3 && p[1] === ':');

roots(tools({ SystemRoot: process.env.SystemRoot, PATH: [sys, node].join(delimiter) }));       // []
roots(tools({ SystemRoot: process.env.SystemRoot, PATH: [sys, node, pwsh].join(delimiter) })); // ['C:\\']
  1. Use the result in a policy that should only allow a project folder (0.9.0 API shown; 1.0.0 run behaves the same):
import { createConfigFromPolicy, getAvailableToolsPolicy, spawnSandboxFromConfig } from '@microsoft/mxc-sdk';

const config = createConfigFromPolicy(
  {
    version: '0.9.0-alpha',
    filesystem: { readwritePaths: [project], readonlyPaths: getAvailableToolsPolicy(process.env).readonlyPaths },
    network: { egress: { default: 'deny' }, ingress: { default: 'deny', hostLoopback: 'deny' } },
  },
  'process',
);
config.process.commandLine = `cmd.exe /d /c dir /b "${process.env.USERPROFILE}" & type "${outsideFile}"`;
config.process.cwd = project;
spawnSandboxFromConfig(config, { usePty: false });
  1. The sandboxed command lists the user profile and prints a file outside the project and outside every tool folder.
  2. Remove C:\ from readonlyPaths and run it again: both are denied (Access is denied), as expected.

Expected behavior

The recommended discovery baseline does not grant read access to the whole system drive. For example:

  • grant only what PowerShell needs at the root: metadata or enumeration of C:\ itself (as wxc-host-prep prepare-system-drive does on the DACL tier, or enumeratePaths where PSEC 1.1 is available), not file contents of the subtree; or
  • return the root under a separate, clearly named field or option so callers opt in; and
  • document the effect on BaseContainer in the README's PowerShell pitfall and the helper's doc comment.

Actual behavior

readonlyPaths contains C:\ whenever pwsh.exe is on PATH, and on BaseContainer the sandboxed process can read and list everything on the system drive that the user can. Callers who follow the README get a sandbox that only restricts writes and network, without any warning.

Activity

  1. added
    Needs-TriageHas not yet been reviewed, classified, and routed.
    Issue-BugSomething is not working as intended.
    OS-WindowsApplies specifically to Windows hosts or Windows behavior.
    on Oct 9, 2026
  2. mvanhorn commented on Oct 10, 2026

    @mvanhorn

    getPowerShellPolicy appended SystemDrive (falling back to C:) plus a trailing slash to readonlyPaths whenever it found pwsh.exe. BaseContainer treats a drive-root readonly path as a recursive read of the subtree, so the grant meant to let PowerShell stat the root became a whole-drive content read.

    The drive root is added only when allowPowerShellDriveRootRead is true; the default is false.

    #1463

  3. added
    Backend-ProcessContainerWindows ProcessContainer behavior, including BaseContainer and AppContainer isolation tiers.
    Priority2High-impact issue affecting key functionality; prioritize for the next appropriate release.
    and removed
    Needs-TriageHas not yet been reviewed, classified, and routed.
    on Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Backend-ProcessContainerWindows ProcessContainer behavior, including BaseContainer and AppContainer isolation tiers.Issue-BugSomething is not working as intended.OS-WindowsApplies specifically to Windows hosts or Windows behavior.Priority2High-impact issue affecting key functionality; prioritize for the next appropriate release.

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions