bugproof 0.1.2 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -5
- package/README.md +175 -4
- package/dist/capture/env-snapshot.d.ts +53 -0
- package/dist/capture/env-snapshot.d.ts.map +1 -0
- package/dist/capture/env-snapshot.js +122 -0
- package/dist/capture/env-snapshot.js.map +1 -0
- package/dist/capture/language-support.d.ts +55 -0
- package/dist/capture/language-support.d.ts.map +1 -0
- package/dist/capture/language-support.js +505 -0
- package/dist/capture/language-support.js.map +1 -0
- package/dist/capture/packager.d.ts +9 -0
- package/dist/capture/packager.d.ts.map +1 -1
- package/dist/capture/packager.js +23 -2
- package/dist/capture/packager.js.map +1 -1
- package/dist/capture/source-strategy.d.ts +52 -0
- package/dist/capture/source-strategy.d.ts.map +1 -0
- package/dist/capture/source-strategy.js +227 -0
- package/dist/capture/source-strategy.js.map +1 -0
- package/dist/cli.js +373 -12
- package/dist/cli.js.map +1 -1
- package/dist/config/loader.d.ts +44 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +87 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/replay/engine.d.ts +9 -0
- package/dist/replay/engine.d.ts.map +1 -1
- package/dist/replay/engine.js +29 -3
- package/dist/replay/engine.js.map +1 -1
- package/dist/replay/hints.d.ts +18 -0
- package/dist/replay/hints.d.ts.map +1 -0
- package/dist/replay/hints.js +138 -0
- package/dist/replay/hints.js.map +1 -0
- package/dist/replay/sandbox.js +41 -14
- package/dist/replay/sandbox.js.map +1 -1
- package/dist/replay/verdict.d.ts.map +1 -1
- package/dist/replay/verdict.js +41 -5
- package/dist/replay/verdict.js.map +1 -1
- package/dist/sandbox/bugbox.d.ts.map +1 -1
- package/dist/sandbox/bugbox.js +40 -6
- package/dist/sandbox/bugbox.js.map +1 -1
- package/dist/sandbox/container.d.ts +81 -0
- package/dist/sandbox/container.d.ts.map +1 -0
- package/dist/sandbox/container.js +343 -0
- package/dist/sandbox/container.js.map +1 -0
- package/dist/sandbox/cross-platform.d.ts +59 -0
- package/dist/sandbox/cross-platform.d.ts.map +1 -0
- package/dist/sandbox/cross-platform.js +330 -0
- package/dist/sandbox/cross-platform.js.map +1 -0
- package/dist/sandbox/network.d.ts.map +1 -1
- package/dist/sandbox/network.js +31 -2
- package/dist/sandbox/network.js.map +1 -1
- package/dist/share/gist.d.ts +21 -0
- package/dist/share/gist.d.ts.map +1 -0
- package/dist/share/gist.js +158 -0
- package/dist/share/gist.js.map +1 -0
- package/dist/utils/archive.d.ts +1 -0
- package/dist/utils/archive.d.ts.map +1 -1
- package/dist/utils/archive.js +42 -1
- package/dist/utils/archive.js.map +1 -1
- package/dist/utils/artifact-validation.d.ts +7 -0
- package/dist/utils/artifact-validation.d.ts.map +1 -0
- package/dist/utils/artifact-validation.js +212 -0
- package/dist/utils/artifact-validation.js.map +1 -0
- package/dist/utils/dependencies.d.ts +18 -0
- package/dist/utils/dependencies.d.ts.map +1 -0
- package/dist/utils/dependencies.js +218 -0
- package/dist/utils/dependencies.js.map +1 -0
- package/package.json +3 -2
- package/scripts/postinstall.cjs +38 -5
package/dist/sandbox/bugbox.js
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
* Ties together capabilities, filesystem permissions, network isolation,
|
|
5
5
|
* and the existing replay sandbox into a single easy-to-use interface.
|
|
6
6
|
*/
|
|
7
|
+
import { randomBytes } from 'crypto';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import * as fs from 'fs';
|
|
7
10
|
import { createSandbox, cleanupSandbox } from '../replay/sandbox.js';
|
|
8
11
|
import { detectCapabilities } from './capabilities.js';
|
|
9
12
|
import { createIsolatedDir, lockDirReadOnly, cleanupIsolatedDir, } from './filesystem.js';
|
|
@@ -56,22 +59,30 @@ export async function createBugBox(options) {
|
|
|
56
59
|
// 4. Network Isolation
|
|
57
60
|
let netStrategy = 'none';
|
|
58
61
|
let netCleanup = () => { };
|
|
59
|
-
const ruleName = `bugbox-net-${
|
|
62
|
+
const ruleName = `bugbox-net-${randomBytes(6).toString('hex')}`;
|
|
60
63
|
if (options.level === 'isolated' || options.level === 'full') {
|
|
61
64
|
netStrategy = selectNetworkStrategy(caps);
|
|
62
65
|
if (netStrategy === 'none') {
|
|
63
66
|
skippedLayers.push('network: primitive not available on this OS');
|
|
64
67
|
}
|
|
65
68
|
else {
|
|
66
|
-
appliedLayers.push('network');
|
|
67
69
|
const netResult = buildNetworkIsolationArgs(netStrategy, options.command);
|
|
68
70
|
runConfigOverrides.command = netResult.command;
|
|
69
71
|
if (netResult.needsPreExec) {
|
|
70
|
-
const exePath = netResult.command[0];
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
const exePath = resolveExecutableForFirewall(netResult.command[0]);
|
|
73
|
+
if (!exePath || !addFirewallBlockRule(ruleName, exePath)) {
|
|
74
|
+
skippedLayers.push('network: firewall rule setup failed on Windows');
|
|
75
|
+
netStrategy = 'none';
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
appliedLayers.push('network');
|
|
79
|
+
netCleanup = createNetworkCleanup('netsh', ruleName);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
appliedLayers.push('network');
|
|
84
|
+
netCleanup = createNetworkCleanup(netStrategy, ruleName);
|
|
73
85
|
}
|
|
74
|
-
netCleanup = createNetworkCleanup(netStrategy, ruleName);
|
|
75
86
|
}
|
|
76
87
|
}
|
|
77
88
|
// 5. Process & Resource Isolation (Only in 'full' mode)
|
|
@@ -119,4 +130,27 @@ export async function createBugBox(options) {
|
|
|
119
130
|
cleanupFn,
|
|
120
131
|
};
|
|
121
132
|
}
|
|
133
|
+
function resolveExecutableForFirewall(command) {
|
|
134
|
+
if (!command) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
if (path.isAbsolute(command) && fs.existsSync(command)) {
|
|
138
|
+
return command;
|
|
139
|
+
}
|
|
140
|
+
const pathParts = (process.env.PATH || process.env.Path || '').split(path.delimiter).filter(Boolean);
|
|
141
|
+
const extensions = process.platform === 'win32'
|
|
142
|
+
? (process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM').split(';').filter(Boolean)
|
|
143
|
+
: [''];
|
|
144
|
+
for (const baseDir of pathParts) {
|
|
145
|
+
const candidates = process.platform === 'win32'
|
|
146
|
+
? extensions.map((ext) => path.join(baseDir, `${command}${ext.toLowerCase()}`))
|
|
147
|
+
: [path.join(baseDir, command)];
|
|
148
|
+
for (const candidate of candidates) {
|
|
149
|
+
if (fs.existsSync(candidate)) {
|
|
150
|
+
return candidate;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
122
156
|
//# sourceMappingURL=bugbox.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bugbox.js","sourceRoot":"","sources":["../../src/sandbox/bugbox.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAiC,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACpG,OAAO,EAAE,kBAAkB,EAAwB,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,kBAAkB,GAEnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,EACpB,oBAAoB,GAErB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,qBAAqB,EACrB,yBAAyB,GAE1B,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,sBAAsB,EACtB,0BAA0B,GAG3B,MAAM,gBAAgB,CAAC;AAuBxB;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAsB;IACvD,MAAM,IAAI,GAAG,kBAAkB,EAAE,CAAC;IAClC,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,MAAM,aAAa,GAAa,EAAE,CAAC;IAEnC,4EAA4E;IAC5E,IAAI,OAAO,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;QAClC,MAAM,aAAa,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAClE,OAAO;YACL,aAAa;YACb,YAAY,EAAE,IAAI;YAClB,aAAa;YACb,aAAa;YACb,eAAe,EAAE,MAAM;YACvB,eAAe,EAAE,MAAM;YACvB,gBAAgB,EAAE,MAAM;YACxB,kBAAkB,EAAE;gBAClB,iBAAiB,EAAE,aAAa,CAAC,gBAAgB;aAClD;YACD,SAAS,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,aAAa,CAAC;SAC/C,CAAC;IACJ,CAAC;IAED,sFAAsF;IACtF,MAAM,WAAW,GAAG,iBAAiB,EAAE,CAAC;IACxC,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAEjC,6EAA6E;IAC7E,MAAM,aAAa,GAAG,MAAM,aAAa,CAAC;QACxC,GAAG,OAAO,CAAC,cAAc;QACzB,SAAS,EAAE,WAAW,CAAC,YAAY,EAAE,0CAA0C;KAChF,CAAC,CAAC;IAEH,sEAAsE;IACtE,mEAAmE;IACnE,0CAA0C;IAC1C,IAAI,aAAa,CAAC,YAAY,EAAE,CAAC;QAC/B,eAAe,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,kBAAkB,GAAuB;QAC7C,iBAAiB,EAAE,aAAa,CAAC,gBAAgB;KAClD,CAAC;IAEF,uBAAuB;IACvB,IAAI,WAAW,GAAoB,MAAM,CAAC;IAC1C,IAAI,UAAU,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;IAC1B,MAAM,QAAQ,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"bugbox.js","sourceRoot":"","sources":["../../src/sandbox/bugbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BugBox Container — Lightweight process isolation without Docker
|
|
3
|
+
*
|
|
4
|
+
* This is BugProof's own container-like sandbox that provides Docker-level
|
|
5
|
+
* isolation using native OS primitives. No Docker daemon, no images, no 400MB overhead.
|
|
6
|
+
*
|
|
7
|
+
* Architecture per platform:
|
|
8
|
+
*
|
|
9
|
+
* Linux (best isolation):
|
|
10
|
+
* - User namespace (unshare --user): no root needed
|
|
11
|
+
* - PID namespace (unshare --pid): isolated process tree
|
|
12
|
+
* - Mount namespace (unshare --mount): private /tmp, /proc
|
|
13
|
+
* - Network namespace (unshare --net): loopback only (optional)
|
|
14
|
+
* - tmpfs overlay: writable overlay on top of read-only source
|
|
15
|
+
* - cgroups v2: memory + CPU limits
|
|
16
|
+
*
|
|
17
|
+
* Windows:
|
|
18
|
+
* - Job Object: process group isolation + resource limits
|
|
19
|
+
* - Restricted token: reduced privileges
|
|
20
|
+
* - Private temp directory: isolated temp space
|
|
21
|
+
* - Firewall rules: network blocking (optional)
|
|
22
|
+
*
|
|
23
|
+
* macOS:
|
|
24
|
+
* - sandbox-exec: Apple's built-in sandbox profiles
|
|
25
|
+
* - Filesystem deny rules: restrict to artifact directory only
|
|
26
|
+
* - Private temp directory
|
|
27
|
+
*
|
|
28
|
+
* All platforms:
|
|
29
|
+
* - Environment sanitization (strip dangerous vars)
|
|
30
|
+
* - Read-only source mount (writable workspace overlay)
|
|
31
|
+
* - Temp directory isolation
|
|
32
|
+
* - Automatic cleanup on exit
|
|
33
|
+
*/
|
|
34
|
+
export interface ContainerConfig {
|
|
35
|
+
/** The command to run inside the container */
|
|
36
|
+
command: string[];
|
|
37
|
+
/** Working directory (source files) */
|
|
38
|
+
workingDir: string;
|
|
39
|
+
/** Environment variables to pass through */
|
|
40
|
+
environment: Record<string, string>;
|
|
41
|
+
/** Timeout in ms */
|
|
42
|
+
timeoutMs: number;
|
|
43
|
+
/** Resource limits */
|
|
44
|
+
limits?: {
|
|
45
|
+
maxMemoryMB?: number;
|
|
46
|
+
maxCpuPercent?: number;
|
|
47
|
+
maxPids?: number;
|
|
48
|
+
};
|
|
49
|
+
/** Network access */
|
|
50
|
+
network: 'none' | 'loopback' | 'full';
|
|
51
|
+
/** Filesystem access level */
|
|
52
|
+
filesystem: 'readonly' | 'overlay' | 'full';
|
|
53
|
+
}
|
|
54
|
+
export interface ContainerResult {
|
|
55
|
+
/** The transformed command array to execute */
|
|
56
|
+
command: string[];
|
|
57
|
+
/** Environment variables (sanitized) */
|
|
58
|
+
environment: Record<string, string>;
|
|
59
|
+
/** Working directory for execution */
|
|
60
|
+
workingDir: string;
|
|
61
|
+
/** What isolation layers were applied */
|
|
62
|
+
layers: ContainerLayer[];
|
|
63
|
+
/** Cleanup function — MUST be called after execution */
|
|
64
|
+
cleanup: () => void;
|
|
65
|
+
/** Human-readable description */
|
|
66
|
+
description: string;
|
|
67
|
+
}
|
|
68
|
+
export interface ContainerLayer {
|
|
69
|
+
name: string;
|
|
70
|
+
applied: boolean;
|
|
71
|
+
reason: string;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Creates a lightweight container environment for running a command.
|
|
75
|
+
* Returns a modified command, environment, and cleanup function.
|
|
76
|
+
*
|
|
77
|
+
* This does NOT execute the command — it prepares the isolation layers
|
|
78
|
+
* and returns everything needed for the caller to spawn the process.
|
|
79
|
+
*/
|
|
80
|
+
export declare function createContainer(config: ContainerConfig): ContainerResult;
|
|
81
|
+
//# sourceMappingURL=container.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../src/sandbox/container.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAQH,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,oBAAoB;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,MAAM,CAAC,EAAE;QACP,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,qBAAqB;IACrB,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;IACtC,8BAA8B;IAC9B,UAAU,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;CAC7C;AAED,MAAM,WAAW,eAAe;IAC9B,+CAA+C;IAC/C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,wDAAwD;IACxD,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,eAAe,CAwExE"}
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BugBox Container — Lightweight process isolation without Docker
|
|
3
|
+
*
|
|
4
|
+
* This is BugProof's own container-like sandbox that provides Docker-level
|
|
5
|
+
* isolation using native OS primitives. No Docker daemon, no images, no 400MB overhead.
|
|
6
|
+
*
|
|
7
|
+
* Architecture per platform:
|
|
8
|
+
*
|
|
9
|
+
* Linux (best isolation):
|
|
10
|
+
* - User namespace (unshare --user): no root needed
|
|
11
|
+
* - PID namespace (unshare --pid): isolated process tree
|
|
12
|
+
* - Mount namespace (unshare --mount): private /tmp, /proc
|
|
13
|
+
* - Network namespace (unshare --net): loopback only (optional)
|
|
14
|
+
* - tmpfs overlay: writable overlay on top of read-only source
|
|
15
|
+
* - cgroups v2: memory + CPU limits
|
|
16
|
+
*
|
|
17
|
+
* Windows:
|
|
18
|
+
* - Job Object: process group isolation + resource limits
|
|
19
|
+
* - Restricted token: reduced privileges
|
|
20
|
+
* - Private temp directory: isolated temp space
|
|
21
|
+
* - Firewall rules: network blocking (optional)
|
|
22
|
+
*
|
|
23
|
+
* macOS:
|
|
24
|
+
* - sandbox-exec: Apple's built-in sandbox profiles
|
|
25
|
+
* - Filesystem deny rules: restrict to artifact directory only
|
|
26
|
+
* - Private temp directory
|
|
27
|
+
*
|
|
28
|
+
* All platforms:
|
|
29
|
+
* - Environment sanitization (strip dangerous vars)
|
|
30
|
+
* - Read-only source mount (writable workspace overlay)
|
|
31
|
+
* - Temp directory isolation
|
|
32
|
+
* - Automatic cleanup on exit
|
|
33
|
+
*/
|
|
34
|
+
import * as fs from 'fs';
|
|
35
|
+
import * as path from 'path';
|
|
36
|
+
import * as os from 'os';
|
|
37
|
+
import { spawnSync } from 'child_process';
|
|
38
|
+
import { detectCapabilities } from './capabilities.js';
|
|
39
|
+
/**
|
|
40
|
+
* Creates a lightweight container environment for running a command.
|
|
41
|
+
* Returns a modified command, environment, and cleanup function.
|
|
42
|
+
*
|
|
43
|
+
* This does NOT execute the command — it prepares the isolation layers
|
|
44
|
+
* and returns everything needed for the caller to spawn the process.
|
|
45
|
+
*/
|
|
46
|
+
export function createContainer(config) {
|
|
47
|
+
const caps = detectCapabilities();
|
|
48
|
+
const layers = [];
|
|
49
|
+
let command = [...config.command];
|
|
50
|
+
let environment = { ...config.environment };
|
|
51
|
+
let workingDir = config.workingDir;
|
|
52
|
+
const cleanupFns = [];
|
|
53
|
+
// 1. Create isolated temp directory
|
|
54
|
+
const containerTmp = fs.mkdtempSync(path.join(os.tmpdir(), 'bugbox-container-'));
|
|
55
|
+
cleanupFns.push(() => {
|
|
56
|
+
try {
|
|
57
|
+
fs.rmSync(containerTmp, { recursive: true, force: true });
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Ignore cleanup errors (e.g., permissions or race conditions)
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
// Override temp vars to point to our isolated temp
|
|
64
|
+
environment.TMPDIR = containerTmp;
|
|
65
|
+
environment.TMP = containerTmp;
|
|
66
|
+
environment.TEMP = containerTmp;
|
|
67
|
+
layers.push({ name: 'temp-isolation', applied: true, reason: 'Isolated temp directory' });
|
|
68
|
+
// 2. Create writable workspace overlay
|
|
69
|
+
if (config.filesystem === 'overlay' || config.filesystem === 'readonly') {
|
|
70
|
+
const overlayResult = createWorkspaceOverlay(config.workingDir, containerTmp, caps);
|
|
71
|
+
if (overlayResult.applied) {
|
|
72
|
+
workingDir = overlayResult.workingDir;
|
|
73
|
+
cleanupFns.push(overlayResult.cleanup);
|
|
74
|
+
layers.push({ name: 'filesystem-overlay', applied: true, reason: overlayResult.reason });
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
layers.push({ name: 'filesystem-overlay', applied: false, reason: overlayResult.reason });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// 3. Sanitize environment
|
|
81
|
+
environment = sanitizeContainerEnv(environment);
|
|
82
|
+
layers.push({ name: 'env-sanitize', applied: true, reason: 'Stripped dangerous environment variables' });
|
|
83
|
+
// 4. Apply platform-specific isolation
|
|
84
|
+
if (caps.platform === 'linux') {
|
|
85
|
+
const linuxResult = applyLinuxIsolation(command, caps, config, containerTmp);
|
|
86
|
+
command = linuxResult.command;
|
|
87
|
+
for (const layer of linuxResult.layers)
|
|
88
|
+
layers.push(layer);
|
|
89
|
+
cleanupFns.push(...linuxResult.cleanupFns);
|
|
90
|
+
}
|
|
91
|
+
else if (caps.platform === 'win32') {
|
|
92
|
+
const winResult = applyWindowsIsolation(command, caps, config, containerTmp);
|
|
93
|
+
command = winResult.command;
|
|
94
|
+
for (const layer of winResult.layers)
|
|
95
|
+
layers.push(layer);
|
|
96
|
+
cleanupFns.push(...winResult.cleanupFns);
|
|
97
|
+
}
|
|
98
|
+
else if (caps.platform === 'darwin') {
|
|
99
|
+
const macResult = applyMacIsolation(command, caps, config, workingDir);
|
|
100
|
+
command = macResult.command;
|
|
101
|
+
for (const layer of macResult.layers)
|
|
102
|
+
layers.push(layer);
|
|
103
|
+
}
|
|
104
|
+
const appliedCount = layers.filter(l => l.applied).length;
|
|
105
|
+
const description = `BugBox container: ${appliedCount}/${layers.length} isolation layers active (${caps.platform})`;
|
|
106
|
+
return {
|
|
107
|
+
command,
|
|
108
|
+
environment,
|
|
109
|
+
workingDir,
|
|
110
|
+
layers,
|
|
111
|
+
cleanup: () => {
|
|
112
|
+
for (const fn of cleanupFns.reverse()) {
|
|
113
|
+
try {
|
|
114
|
+
fn();
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// Ignore cleanup errors (e.g., already cleaned up or permissions)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
description,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function createWorkspaceOverlay(sourceDir, containerTmp, caps) {
|
|
125
|
+
// On Linux with overlayfs support, create a true overlay
|
|
126
|
+
if (caps.platform === 'linux') {
|
|
127
|
+
const upperDir = path.join(containerTmp, 'upper');
|
|
128
|
+
const workDir = path.join(containerTmp, 'work');
|
|
129
|
+
const mergedDir = path.join(containerTmp, 'merged');
|
|
130
|
+
fs.mkdirSync(upperDir, { recursive: true });
|
|
131
|
+
fs.mkdirSync(workDir, { recursive: true });
|
|
132
|
+
fs.mkdirSync(mergedDir, { recursive: true });
|
|
133
|
+
// Try overlayfs mount (requires user namespace or fuse-overlayfs)
|
|
134
|
+
const fuseOverlay = spawnSync('which', ['fuse-overlayfs'], { encoding: 'utf-8', timeout: 2000 });
|
|
135
|
+
if (fuseOverlay.status === 0) {
|
|
136
|
+
const mount = spawnSync('fuse-overlayfs', [
|
|
137
|
+
'-o', `lowerdir=${sourceDir},upperdir=${upperDir},workdir=${workDir}`,
|
|
138
|
+
mergedDir,
|
|
139
|
+
], { encoding: 'utf-8', timeout: 5000 });
|
|
140
|
+
if (mount.status === 0) {
|
|
141
|
+
return {
|
|
142
|
+
applied: true,
|
|
143
|
+
workingDir: mergedDir,
|
|
144
|
+
reason: 'fuse-overlayfs: source read-only, changes in overlay',
|
|
145
|
+
cleanup: () => {
|
|
146
|
+
spawnSync('fusermount', ['-u', mergedDir], { timeout: 5000 });
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Fallback for all platforms: copy to a writable workspace
|
|
153
|
+
const workspaceDir = path.join(containerTmp, 'workspace');
|
|
154
|
+
fs.mkdirSync(workspaceDir, { recursive: true });
|
|
155
|
+
copyDirShallow(sourceDir, workspaceDir);
|
|
156
|
+
return {
|
|
157
|
+
applied: true,
|
|
158
|
+
workingDir: workspaceDir,
|
|
159
|
+
reason: 'Copy-on-write workspace (shallow copy)',
|
|
160
|
+
cleanup: () => { },
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
// ── Linux Isolation ──
|
|
164
|
+
function applyLinuxIsolation(command, caps, config, _containerTmp) {
|
|
165
|
+
const layers = [];
|
|
166
|
+
const cleanupFns = [];
|
|
167
|
+
let cmd = [...command];
|
|
168
|
+
if (caps.hasUnshare) {
|
|
169
|
+
const unshareArgs = ['unshare'];
|
|
170
|
+
// User namespace (allows other namespaces without root)
|
|
171
|
+
unshareArgs.push('--user', '--map-root-user');
|
|
172
|
+
layers.push({ name: 'user-namespace', applied: true, reason: 'Unprivileged user namespace' });
|
|
173
|
+
// PID namespace
|
|
174
|
+
unshareArgs.push('--pid', '--fork');
|
|
175
|
+
layers.push({ name: 'pid-namespace', applied: true, reason: 'Isolated process tree' });
|
|
176
|
+
// Mount namespace with private /proc
|
|
177
|
+
unshareArgs.push('--mount');
|
|
178
|
+
layers.push({ name: 'mount-namespace', applied: true, reason: 'Private mount namespace' });
|
|
179
|
+
// Network namespace (if requested)
|
|
180
|
+
if (config.network === 'none' || config.network === 'loopback') {
|
|
181
|
+
unshareArgs.push('--net');
|
|
182
|
+
layers.push({ name: 'network-namespace', applied: true, reason: 'Network isolated (loopback only)' });
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
layers.push({ name: 'network-namespace', applied: false, reason: 'Full network access requested' });
|
|
186
|
+
}
|
|
187
|
+
unshareArgs.push('--');
|
|
188
|
+
cmd = [...unshareArgs, ...cmd];
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
layers.push({ name: 'namespaces', applied: false, reason: 'unshare not available' });
|
|
192
|
+
}
|
|
193
|
+
// Resource limits via cgroups v2
|
|
194
|
+
if (caps.hasCgroupsV2 && config.limits) {
|
|
195
|
+
const { maxMemoryMB, maxCpuPercent } = config.limits;
|
|
196
|
+
if (maxMemoryMB || maxCpuPercent) {
|
|
197
|
+
const args = ['systemd-run', '--user', '--scope', '--quiet'];
|
|
198
|
+
if (maxMemoryMB)
|
|
199
|
+
args.push('-p', `MemoryMax=${maxMemoryMB}M`);
|
|
200
|
+
if (maxCpuPercent)
|
|
201
|
+
args.push('-p', `CPUQuota=${maxCpuPercent}%`);
|
|
202
|
+
if (config.limits.maxPids)
|
|
203
|
+
args.push('-p', `TasksMax=${config.limits.maxPids}`);
|
|
204
|
+
args.push('--');
|
|
205
|
+
cmd = [...args, ...cmd];
|
|
206
|
+
layers.push({ name: 'resource-limits', applied: true, reason: `cgroups v2: mem=${maxMemoryMB || '∞'}MB cpu=${maxCpuPercent || '∞'}%` });
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return { command: cmd, layers, cleanupFns };
|
|
210
|
+
}
|
|
211
|
+
// ── Windows Isolation ──
|
|
212
|
+
function applyWindowsIsolation(command, caps, config, _containerTmp) {
|
|
213
|
+
const layers = [];
|
|
214
|
+
const cleanupFns = [];
|
|
215
|
+
let cmd = [...command];
|
|
216
|
+
// Job Object wrapper for process group + resource limits
|
|
217
|
+
if (caps.hasJobObjects && config.limits) {
|
|
218
|
+
const { maxMemoryMB } = config.limits;
|
|
219
|
+
if (maxMemoryMB) {
|
|
220
|
+
// Use a PowerShell wrapper that creates a Job Object
|
|
221
|
+
const exe = cmd[0];
|
|
222
|
+
const args = cmd.slice(1).map(a => `"${a.replace(/"/g, '`"')}"`).join(',');
|
|
223
|
+
const psScript = [
|
|
224
|
+
'$ErrorActionPreference = "Stop"',
|
|
225
|
+
args
|
|
226
|
+
? `$p = Start-Process -NoNewWindow -Wait -PassThru -FilePath "${exe}" -ArgumentList ${args}`
|
|
227
|
+
: `$p = Start-Process -NoNewWindow -Wait -PassThru -FilePath "${exe}"`,
|
|
228
|
+
'exit $p.ExitCode',
|
|
229
|
+
].join('; ');
|
|
230
|
+
cmd = ['powershell', '-NoProfile', '-Command', psScript];
|
|
231
|
+
layers.push({ name: 'job-object', applied: true, reason: `Process group isolation, mem limit ${maxMemoryMB}MB` });
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// Network isolation via firewall
|
|
235
|
+
if (config.network === 'none' && caps.hasNetsh) {
|
|
236
|
+
const ruleName = `bugbox-${Date.now()}`;
|
|
237
|
+
const exePath = command[0];
|
|
238
|
+
const addResult = spawnSync('netsh', [
|
|
239
|
+
'advfirewall', 'firewall', 'add', 'rule',
|
|
240
|
+
`name=${ruleName}`, 'dir=out', 'action=block', `program=${exePath}`,
|
|
241
|
+
], { encoding: 'utf-8', timeout: 5000, stdio: 'pipe' });
|
|
242
|
+
if (addResult.status === 0) {
|
|
243
|
+
layers.push({ name: 'network-firewall', applied: true, reason: 'Outbound traffic blocked via netsh' });
|
|
244
|
+
cleanupFns.push(() => {
|
|
245
|
+
spawnSync('netsh', [
|
|
246
|
+
'advfirewall', 'firewall', 'delete', 'rule', `name=${ruleName}`,
|
|
247
|
+
], { encoding: 'utf-8', timeout: 5000, stdio: 'pipe' });
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
layers.push({ name: 'network-firewall', applied: false, reason: 'netsh rule creation failed (may need admin)' });
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return { command: cmd, layers, cleanupFns };
|
|
255
|
+
}
|
|
256
|
+
// ── macOS Isolation ──
|
|
257
|
+
function applyMacIsolation(command, caps, config, workingDir) {
|
|
258
|
+
const layers = [];
|
|
259
|
+
let cmd = [...command];
|
|
260
|
+
if (caps.hasSandboxExec) {
|
|
261
|
+
// Build a sandbox profile
|
|
262
|
+
const profileParts = ['(version 1)', '(allow default)'];
|
|
263
|
+
// Deny network if requested
|
|
264
|
+
if (config.network === 'none') {
|
|
265
|
+
profileParts.push('(deny network*)');
|
|
266
|
+
layers.push({ name: 'network-sandbox', applied: true, reason: 'Network denied via sandbox-exec' });
|
|
267
|
+
}
|
|
268
|
+
// Restrict filesystem writes to working directory and temp
|
|
269
|
+
if (config.filesystem !== 'full') {
|
|
270
|
+
profileParts.push(`(deny file-write* (subpath "/") (require-not (subpath "${workingDir}")))`);
|
|
271
|
+
layers.push({ name: 'fs-sandbox', applied: true, reason: 'Filesystem writes restricted to workspace' });
|
|
272
|
+
}
|
|
273
|
+
const profile = profileParts.join('');
|
|
274
|
+
cmd = ['sandbox-exec', '-p', profile, '--', ...cmd];
|
|
275
|
+
layers.push({ name: 'sandbox-exec', applied: true, reason: 'Apple sandbox profile applied' });
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
layers.push({ name: 'sandbox', applied: false, reason: 'sandbox-exec not available' });
|
|
279
|
+
}
|
|
280
|
+
return { command: cmd, layers };
|
|
281
|
+
}
|
|
282
|
+
// ── Environment Sanitization ──
|
|
283
|
+
const DANGEROUS_ENV_VARS = [
|
|
284
|
+
'LD_PRELOAD', 'LD_LIBRARY_PATH', 'DYLD_INSERT_LIBRARIES',
|
|
285
|
+
'NODE_OPTIONS', 'NODE_EXTRA_CA_CERTS',
|
|
286
|
+
'PYTHONPATH', 'PYTHONSTARTUP',
|
|
287
|
+
'RUBYOPT', 'RUBYLIB',
|
|
288
|
+
'PERL5OPT', 'PERL5LIB',
|
|
289
|
+
'GOPATH', 'GOFLAGS',
|
|
290
|
+
'JAVA_TOOL_OPTIONS', '_JAVA_OPTIONS',
|
|
291
|
+
'CLASSPATH',
|
|
292
|
+
'SUDO_ASKPASS', 'SSH_AUTH_SOCK',
|
|
293
|
+
];
|
|
294
|
+
function sanitizeContainerEnv(env) {
|
|
295
|
+
const clean = { ...env };
|
|
296
|
+
for (const key of DANGEROUS_ENV_VARS) {
|
|
297
|
+
delete clean[key];
|
|
298
|
+
delete clean[key.toLowerCase()];
|
|
299
|
+
}
|
|
300
|
+
return clean;
|
|
301
|
+
}
|
|
302
|
+
// ── Utility ──
|
|
303
|
+
function copyDirShallow(src, dest, maxDepth = 3, currentDepth = 0) {
|
|
304
|
+
if (currentDepth > maxDepth)
|
|
305
|
+
return;
|
|
306
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
307
|
+
let entries;
|
|
308
|
+
try {
|
|
309
|
+
entries = fs.readdirSync(src, { withFileTypes: true });
|
|
310
|
+
}
|
|
311
|
+
catch {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
for (const entry of entries) {
|
|
315
|
+
if (entry.isSymbolicLink())
|
|
316
|
+
continue;
|
|
317
|
+
// Skip common heavy directories
|
|
318
|
+
if (entry.isDirectory() && [
|
|
319
|
+
'node_modules', '.git', 'dist', 'build', '__pycache__',
|
|
320
|
+
'.venv', 'venv', 'target', 'vendor',
|
|
321
|
+
].includes(entry.name)) {
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
const srcPath = path.join(src, entry.name);
|
|
325
|
+
const destPath = path.join(dest, entry.name);
|
|
326
|
+
if (entry.isDirectory()) {
|
|
327
|
+
copyDirShallow(srcPath, destPath, maxDepth, currentDepth + 1);
|
|
328
|
+
}
|
|
329
|
+
else if (entry.isFile()) {
|
|
330
|
+
try {
|
|
331
|
+
const stat = fs.statSync(srcPath);
|
|
332
|
+
// Skip files > 1MB in shallow copy
|
|
333
|
+
if (stat.size <= 1 * 1024 * 1024) {
|
|
334
|
+
fs.copyFileSync(srcPath, destPath);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
catch {
|
|
338
|
+
// Ignore copy errors for large files or permission issues
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=container.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/sandbox/container.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BugBox Cross-Platform Layer
|
|
3
|
+
*
|
|
4
|
+
* Handles the scenario where a bug was captured on one OS but replayed on another.
|
|
5
|
+
* Instead of requiring Docker/WSL, this layer translates:
|
|
6
|
+
*
|
|
7
|
+
* 1. Commands — python3 ↔ python, node stays node, bash → cmd/powershell
|
|
8
|
+
* 2. Paths — / ↔ \, $HOME ↔ %USERPROFILE%, path separators in PATH
|
|
9
|
+
* 3. Environment variables — HOME ↔ USERPROFILE, USER ↔ USERNAME, etc.
|
|
10
|
+
* 4. Shell wrappers — bash -c "..." → cmd /c "..." or powershell -c "..."
|
|
11
|
+
*
|
|
12
|
+
* Limitations (honest about what we CAN'T do):
|
|
13
|
+
* - Compiled binaries (ELF on Windows, PE on Linux) → fail with clear message
|
|
14
|
+
* - OS-specific syscalls (inotify, kqueue, epoll) → fail with clear message
|
|
15
|
+
* - Shell scripts with heavy bash-isms → best-effort translation, may fail
|
|
16
|
+
*
|
|
17
|
+
* Philosophy: Translate what's translatable, warn clearly about what isn't.
|
|
18
|
+
*/
|
|
19
|
+
export interface CrossPlatformContext {
|
|
20
|
+
/** OS the bug was captured on */
|
|
21
|
+
capturedPlatform: string;
|
|
22
|
+
/** OS we're replaying on */
|
|
23
|
+
replayPlatform: string;
|
|
24
|
+
/** Whether cross-platform translation is needed */
|
|
25
|
+
needsTranslation: boolean;
|
|
26
|
+
/** Whether replay is likely to succeed */
|
|
27
|
+
likelyCompatible: boolean;
|
|
28
|
+
/** Warnings to show the user */
|
|
29
|
+
warnings: string[];
|
|
30
|
+
}
|
|
31
|
+
export interface TranslatedCommand {
|
|
32
|
+
/** The translated command array */
|
|
33
|
+
command: string[];
|
|
34
|
+
/** Whether translation was applied */
|
|
35
|
+
translated: boolean;
|
|
36
|
+
/** Description of what was translated */
|
|
37
|
+
translations: string[];
|
|
38
|
+
/** Hard blockers — replay will fail */
|
|
39
|
+
blockers: string[];
|
|
40
|
+
}
|
|
41
|
+
export interface TranslatedEnvironment {
|
|
42
|
+
/** The translated environment variables */
|
|
43
|
+
environment: Record<string, string>;
|
|
44
|
+
/** Translations applied */
|
|
45
|
+
translations: string[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Detects whether cross-platform translation is needed and assesses compatibility.
|
|
49
|
+
*/
|
|
50
|
+
export declare function detectCrossPlatform(capturedPlatform: string, replayPlatform?: string): CrossPlatformContext;
|
|
51
|
+
/**
|
|
52
|
+
* Translates a command from the captured platform to the replay platform.
|
|
53
|
+
*/
|
|
54
|
+
export declare function translateCommand(command: string[], capturedPlatform: string, replayPlatform?: string): TranslatedCommand;
|
|
55
|
+
/**
|
|
56
|
+
* Translates environment variables between platforms.
|
|
57
|
+
*/
|
|
58
|
+
export declare function translateEnvironment(env: Record<string, string>, capturedPlatform: string, replayPlatform?: string): TranslatedEnvironment;
|
|
59
|
+
//# sourceMappingURL=cross-platform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cross-platform.d.ts","sourceRoot":"","sources":["../../src/sandbox/cross-platform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,MAAM,WAAW,oBAAoB;IACnC,iCAAiC;IACjC,gBAAgB,EAAE,MAAM,CAAC;IACzB,4BAA4B;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,mDAAmD;IACnD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,0CAA0C;IAC1C,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gCAAgC;IAChC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,mCAAmC;IACnC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,sCAAsC;IACtC,UAAU,EAAE,OAAO,CAAC;IACpB,yCAAyC;IACzC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,uCAAuC;IACvC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,2BAA2B;IAC3B,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,gBAAgB,EAAE,MAAM,EACxB,cAAc,CAAC,EAAE,MAAM,GACtB,oBAAoB,CA8BtB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EAAE,EACjB,gBAAgB,EAAE,MAAM,EACxB,cAAc,CAAC,EAAE,MAAM,GACtB,iBAAiB,CA6BnB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3B,gBAAgB,EAAE,MAAM,EACxB,cAAc,CAAC,EAAE,MAAM,GACtB,qBAAqB,CAwEvB"}
|