This commit is contained in:
@@ -62,6 +62,7 @@ export interface ToolContext {
|
||||
allowedCommands?: string[]; // Bash ツールで許可するコマンド名一覧 (省略時は DEFAULT_ALLOWED_COMMANDS)
|
||||
bashUnrestricted?: boolean; // true: skip the command whitelist (bwrap/exec is chosen by bashSandbox, not this)
|
||||
bashSandbox?: 'auto' | 'always' | 'off'; // サンドボックス機構の選択 (config.safety.bashSandbox 由来)
|
||||
bashAllowNetwork?: boolean; // true: bwrap サンドボックスで host network を許可 (--unshare-net を外す。config.safety.bashAllowNetwork 由来)
|
||||
skillCatalog?: import('../skills.js').SkillCatalog;
|
||||
toolsConfig?: ToolsConfig;
|
||||
searchFilter?: SearchFilterConfig; // AppConfig.searchFilter (トップレベル)
|
||||
@@ -1007,6 +1008,7 @@ async function executeBash(input: Record<string, unknown>, ctx: ToolContext): Pr
|
||||
}
|
||||
const result: SandboxedBashResult = await executeSandboxedBash(
|
||||
command, ctx.workspacePath, timeoutSec, BASH_MAX_BUFFER_BYTES, ctx.abortSignal, skillBinds,
|
||||
ctx.bashAllowNetwork === true,
|
||||
);
|
||||
const out = result.isError ? result.output : capOutput(result.output, 'stdout');
|
||||
logBashHistory(ctx.workspacePath, command, result.isError, Date.now() - startedAt, {
|
||||
|
||||
@@ -245,6 +245,27 @@ describe('buildBwrapArgs sandboxing', () => {
|
||||
expect(i).toBeGreaterThan(-1);
|
||||
expect(args).toContain('HOME');
|
||||
});
|
||||
|
||||
it('unshares network by default (allowNetwork omitted)', () => {
|
||||
const args = buildBwrapArgs('echo hi', '/work/ws');
|
||||
expect(args).toContain('--unshare-net');
|
||||
});
|
||||
|
||||
it('keeps host network when allowNetwork=true (drops only --unshare-net)', () => {
|
||||
const args = buildBwrapArgs('echo hi', '/work/ws', undefined, process.env, true);
|
||||
expect(args).not.toContain('--unshare-net');
|
||||
// all other isolations remain
|
||||
expect(args).toContain('--unshare-user');
|
||||
expect(args).toContain('--unshare-ipc');
|
||||
expect(args).toContain('--unshare-pid');
|
||||
expect(args).toContain('--unshare-uts');
|
||||
expect(args).toContain('--unshare-cgroup');
|
||||
});
|
||||
|
||||
it('unshares network when allowNetwork=false (explicit)', () => {
|
||||
const args = buildBwrapArgs('echo hi', '/work/ws', undefined, process.env, false);
|
||||
expect(args).toContain('--unshare-net');
|
||||
});
|
||||
});
|
||||
|
||||
describe('checkBwrapAvailable', () => {
|
||||
|
||||
@@ -36,6 +36,7 @@ export function buildBwrapArgs(
|
||||
workspacePath: string,
|
||||
extraReadOnlyBinds?: ExtraReadOnlyBind[],
|
||||
parentEnv: NodeJS.ProcessEnv = process.env,
|
||||
allowNetwork: boolean = false,
|
||||
): string[] {
|
||||
const args: string[] = [];
|
||||
|
||||
@@ -70,7 +71,13 @@ export function buildBwrapArgs(
|
||||
|
||||
args.push('--chdir', workspacePath);
|
||||
args.push('--die-with-parent');
|
||||
args.push('--unshare-user', '--unshare-ipc', '--unshare-pid', '--unshare-uts', '--unshare-cgroup', '--unshare-net');
|
||||
// Network isolation is the one --unshare-* that's optional. When
|
||||
// allowNetwork is true (config.safety.bashAllowNetwork) the sandbox keeps host
|
||||
// network so pip/npm/curl work; all other namespaces stay unshared.
|
||||
args.push('--unshare-user', '--unshare-ipc', '--unshare-pid', '--unshare-uts', '--unshare-cgroup');
|
||||
if (!allowNetwork) {
|
||||
args.push('--unshare-net');
|
||||
}
|
||||
|
||||
args.push('--clearenv');
|
||||
const sandboxEnv = buildSandboxEnv(parentEnv, workspacePath);
|
||||
@@ -124,8 +131,9 @@ export async function executeSandboxedBash(
|
||||
maxBuffer: number,
|
||||
abortSignal?: AbortSignal,
|
||||
extraReadOnlyBinds?: ExtraReadOnlyBind[],
|
||||
allowNetwork: boolean = false,
|
||||
): Promise<SandboxedBashResult> {
|
||||
const args = buildBwrapArgs(command, workspacePath, extraReadOnlyBinds);
|
||||
const args = buildBwrapArgs(command, workspacePath, extraReadOnlyBinds, process.env, allowNetwork);
|
||||
|
||||
if (abortSignal?.aborted) {
|
||||
return { output: 'Cancelled before sandbox bash launch', isError: true };
|
||||
|
||||
Reference in New Issue
Block a user