harden sandbox escape vectors for bash disabled/restricted modes (#257)

* harden sandbox escape vectors for bash disabled/restricted modes

block git config injection (-c flag as subcommand), dangerous subcommands
(config, submodule, rebase, bisect), code-executing arg flags (--exec,
--extcmd), .gitattributes/.gitmodules writes, and package lifecycle scripts.
add retry logic to test runner for transient failures. add security unit
tests and adhoc attack tests.

Co-authored-by: Cursor <cursoragent@cursor.com>

* only filter subcommands in nobash, remove nobash from ui

* use regex matching

* iterate on tests

* simplify githooks

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
David Blass
2026-02-11 02:02:41 +00:00
committed by pullfrog[bot]
parent f37d02b292
commit bc28c658f2
32 changed files with 2515 additions and 1048 deletions
+4 -4
View File
@@ -1,9 +1,9 @@
import { log } from "../utils/cli.ts";
import { installNodeDependencies } from "./installNodeDependencies.ts";
import { installPythonDependencies } from "./installPythonDependencies.ts";
import type { PrepDefinition, PrepResult } from "./types.ts";
import type { PrepDefinition, PrepOptions, PrepResult } from "./types.ts";
export type { PrepResult } from "./types.ts";
export type { PrepOptions, PrepResult } from "./types.ts";
// register all prep steps here
const prepSteps: PrepDefinition[] = [installNodeDependencies, installPythonDependencies];
@@ -12,7 +12,7 @@ const prepSteps: PrepDefinition[] = [installNodeDependencies, installPythonDepen
* run all prep steps sequentially.
* failures are logged as warnings but don't stop the run.
*/
export async function runPrepPhase(): Promise<PrepResult[]> {
export async function runPrepPhase(options: PrepOptions): Promise<PrepResult[]> {
log.debug("» starting prep phase...");
const startTime = Date.now();
const results: PrepResult[] = [];
@@ -25,7 +25,7 @@ export async function runPrepPhase(): Promise<PrepResult[]> {
}
log.debug(`» running ${step.name}...`);
const result = await step.run();
const result = await step.run(options);
results.push(result);
if (result.dependenciesInstalled) {