bugproof 0.1.1

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.
Files changed (110) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/README.md +256 -0
  3. package/assets/icon-16x16.png +0 -0
  4. package/assets/icon-32x32.png +0 -0
  5. package/assets/icon-512x512.png +0 -0
  6. package/dist/capture/engine.d.ts +12 -0
  7. package/dist/capture/engine.d.ts.map +1 -0
  8. package/dist/capture/engine.js +129 -0
  9. package/dist/capture/engine.js.map +1 -0
  10. package/dist/capture/packager.d.ts +39 -0
  11. package/dist/capture/packager.d.ts.map +1 -0
  12. package/dist/capture/packager.js +145 -0
  13. package/dist/capture/packager.js.map +1 -0
  14. package/dist/cli.d.ts +3 -0
  15. package/dist/cli.d.ts.map +1 -0
  16. package/dist/cli.js +538 -0
  17. package/dist/cli.js.map +1 -0
  18. package/dist/diff/engine.d.ts +28 -0
  19. package/dist/diff/engine.d.ts.map +1 -0
  20. package/dist/diff/engine.js +88 -0
  21. package/dist/diff/engine.js.map +1 -0
  22. package/dist/replay/engine.d.ts +41 -0
  23. package/dist/replay/engine.d.ts.map +1 -0
  24. package/dist/replay/engine.js +69 -0
  25. package/dist/replay/engine.js.map +1 -0
  26. package/dist/replay/sandbox.d.ts +33 -0
  27. package/dist/replay/sandbox.d.ts.map +1 -0
  28. package/dist/replay/sandbox.js +167 -0
  29. package/dist/replay/sandbox.js.map +1 -0
  30. package/dist/replay/verdict.d.ts +8 -0
  31. package/dist/replay/verdict.d.ts.map +1 -0
  32. package/dist/replay/verdict.js +32 -0
  33. package/dist/replay/verdict.js.map +1 -0
  34. package/dist/sandbox/bugbox.d.ts +38 -0
  35. package/dist/sandbox/bugbox.d.ts.map +1 -0
  36. package/dist/sandbox/bugbox.js +122 -0
  37. package/dist/sandbox/bugbox.js.map +1 -0
  38. package/dist/sandbox/capabilities.d.ts +33 -0
  39. package/dist/sandbox/capabilities.d.ts.map +1 -0
  40. package/dist/sandbox/capabilities.js +53 -0
  41. package/dist/sandbox/capabilities.js.map +1 -0
  42. package/dist/sandbox/filesystem.d.ts +50 -0
  43. package/dist/sandbox/filesystem.d.ts.map +1 -0
  44. package/dist/sandbox/filesystem.js +134 -0
  45. package/dist/sandbox/filesystem.js.map +1 -0
  46. package/dist/sandbox/network.d.ts +68 -0
  47. package/dist/sandbox/network.d.ts.map +1 -0
  48. package/dist/sandbox/network.js +136 -0
  49. package/dist/sandbox/network.js.map +1 -0
  50. package/dist/sandbox/process.d.ts +17 -0
  51. package/dist/sandbox/process.d.ts.map +1 -0
  52. package/dist/sandbox/process.js +30 -0
  53. package/dist/sandbox/process.js.map +1 -0
  54. package/dist/sandbox/resources.d.ts +21 -0
  55. package/dist/sandbox/resources.d.ts.map +1 -0
  56. package/dist/sandbox/resources.js +60 -0
  57. package/dist/sandbox/resources.js.map +1 -0
  58. package/dist/types/artifact.d.ts +57 -0
  59. package/dist/types/artifact.d.ts.map +1 -0
  60. package/dist/types/artifact.js +2 -0
  61. package/dist/types/artifact.js.map +1 -0
  62. package/dist/types/failure.d.ts +12 -0
  63. package/dist/types/failure.d.ts.map +1 -0
  64. package/dist/types/failure.js +2 -0
  65. package/dist/types/failure.js.map +1 -0
  66. package/dist/utils/archive.d.ts +13 -0
  67. package/dist/utils/archive.d.ts.map +1 -0
  68. package/dist/utils/archive.js +39 -0
  69. package/dist/utils/archive.js.map +1 -0
  70. package/dist/utils/associations.d.ts +10 -0
  71. package/dist/utils/associations.d.ts.map +1 -0
  72. package/dist/utils/associations.js +46 -0
  73. package/dist/utils/associations.js.map +1 -0
  74. package/dist/utils/exclude.d.ts +12 -0
  75. package/dist/utils/exclude.d.ts.map +1 -0
  76. package/dist/utils/exclude.js +42 -0
  77. package/dist/utils/exclude.js.map +1 -0
  78. package/dist/utils/fingerprint.d.ts +16 -0
  79. package/dist/utils/fingerprint.d.ts.map +1 -0
  80. package/dist/utils/fingerprint.js +72 -0
  81. package/dist/utils/fingerprint.js.map +1 -0
  82. package/dist/utils/git.d.ts +13 -0
  83. package/dist/utils/git.d.ts.map +1 -0
  84. package/dist/utils/git.js +41 -0
  85. package/dist/utils/git.js.map +1 -0
  86. package/dist/utils/json-output.d.ts +36 -0
  87. package/dist/utils/json-output.d.ts.map +1 -0
  88. package/dist/utils/json-output.js +49 -0
  89. package/dist/utils/json-output.js.map +1 -0
  90. package/dist/utils/paths.d.ts +19 -0
  91. package/dist/utils/paths.d.ts.map +1 -0
  92. package/dist/utils/paths.js +43 -0
  93. package/dist/utils/paths.js.map +1 -0
  94. package/dist/utils/secrets.d.ts +13 -0
  95. package/dist/utils/secrets.d.ts.map +1 -0
  96. package/dist/utils/secrets.js +52 -0
  97. package/dist/utils/secrets.js.map +1 -0
  98. package/dist/utils/security.d.ts +27 -0
  99. package/dist/utils/security.d.ts.map +1 -0
  100. package/dist/utils/security.js +75 -0
  101. package/dist/utils/security.js.map +1 -0
  102. package/dist/utils/ui.d.ts +31 -0
  103. package/dist/utils/ui.d.ts.map +1 -0
  104. package/dist/utils/ui.js +54 -0
  105. package/dist/utils/ui.js.map +1 -0
  106. package/package.json +80 -0
  107. package/scripts/bugproof-file-association-linux.sh +80 -0
  108. package/scripts/bugproof-file-association-macos.sh +48 -0
  109. package/scripts/bugproof-file-association-windows.reg +44 -0
  110. package/scripts/postinstall.cjs +215 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bugbox.js","sourceRoot":"","sources":["../../src/sandbox/bugbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Bug-Box Platform Capabilities Detection
3
+ *
4
+ * Probes the current OS for available isolation primitives.
5
+ * Each check is safe, unprivileged, and fast (<50ms per probe).
6
+ * Results are used by bugbox.ts to decide which isolation layers to apply.
7
+ */
8
+ export interface PlatformCapabilities {
9
+ /** Current OS: 'linux', 'win32', or 'darwin' */
10
+ platform: NodeJS.Platform;
11
+ /** Linux: can we run `unshare` for PID/network namespace isolation? */
12
+ hasUnshare: boolean;
13
+ /** Linux: is cgroups v2 available for resource limits? */
14
+ hasCgroupsV2: boolean;
15
+ /** Windows: Job Objects are always available for process/resource limits */
16
+ hasJobObjects: boolean;
17
+ /** Windows: can we create firewall rules via `netsh`? */
18
+ hasNetsh: boolean;
19
+ /** macOS: can we use `sandbox-exec` for profile-based sandboxing? */
20
+ hasSandboxExec: boolean;
21
+ }
22
+ /**
23
+ * Checks whether a command is available on the system PATH.
24
+ * Uses `where` on Windows and `which` on Unix.
25
+ * Never throws — returns false for any error.
26
+ */
27
+ export declare function commandExists(name: string): boolean;
28
+ /**
29
+ * Detects which isolation primitives are available on the current platform.
30
+ * Safe to call repeatedly — each call re-probes (no caching).
31
+ */
32
+ export declare function detectCapabilities(): PlatformCapabilities;
33
+ //# sourceMappingURL=capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/sandbox/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,MAAM,WAAW,oBAAoB;IACnC,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC1B,uEAAuE;IACvE,UAAU,EAAE,OAAO,CAAC;IACpB,0DAA0D;IAC1D,YAAY,EAAE,OAAO,CAAC;IACtB,4EAA4E;IAC5E,aAAa,EAAE,OAAO,CAAC;IACvB,yDAAyD;IACzD,QAAQ,EAAE,OAAO,CAAC;IAClB,qEAAqE;IACrE,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAcnD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,oBAAoB,CAuBzD"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Bug-Box Platform Capabilities Detection
3
+ *
4
+ * Probes the current OS for available isolation primitives.
5
+ * Each check is safe, unprivileged, and fast (<50ms per probe).
6
+ * Results are used by bugbox.ts to decide which isolation layers to apply.
7
+ */
8
+ import * as os from 'os';
9
+ import * as fs from 'fs';
10
+ import { spawnSync } from 'child_process';
11
+ /**
12
+ * Checks whether a command is available on the system PATH.
13
+ * Uses `where` on Windows and `which` on Unix.
14
+ * Never throws — returns false for any error.
15
+ */
16
+ export function commandExists(name) {
17
+ if (!name || !name.trim())
18
+ return false;
19
+ try {
20
+ const cmd = os.platform() === 'win32' ? 'where' : 'which';
21
+ const result = spawnSync(cmd, [name], {
22
+ encoding: 'utf-8',
23
+ timeout: 3000,
24
+ stdio: ['pipe', 'pipe', 'pipe'],
25
+ });
26
+ return result.status === 0;
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ }
32
+ /**
33
+ * Detects which isolation primitives are available on the current platform.
34
+ * Safe to call repeatedly — each call re-probes (no caching).
35
+ */
36
+ export function detectCapabilities() {
37
+ const platform = os.platform();
38
+ return {
39
+ platform,
40
+ // Linux: check for `unshare` (user namespace isolation, no root needed)
41
+ hasUnshare: platform === 'linux' && commandExists('unshare'),
42
+ // Linux: check for cgroups v2 unified hierarchy
43
+ hasCgroupsV2: platform === 'linux' &&
44
+ fs.existsSync('/sys/fs/cgroup/cgroup.controllers'),
45
+ // Windows: Job Objects are a built-in Win32 API, always available
46
+ hasJobObjects: platform === 'win32',
47
+ // Windows: netsh for firewall rules
48
+ hasNetsh: platform === 'win32' && commandExists('netsh'),
49
+ // macOS: sandbox-exec for profile-based sandboxing
50
+ hasSandboxExec: platform === 'darwin' && commandExists('sandbox-exec'),
51
+ };
52
+ }
53
+ //# sourceMappingURL=capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/sandbox/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAiB1C;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;QAAE,OAAO,KAAK,CAAC;IAExC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,QAAQ,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;QAC1D,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE;YACpC,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;IAE/B,OAAO;QACL,QAAQ;QAER,wEAAwE;QACxE,UAAU,EAAE,QAAQ,KAAK,OAAO,IAAI,aAAa,CAAC,SAAS,CAAC;QAE5D,gDAAgD;QAChD,YAAY,EACV,QAAQ,KAAK,OAAO;YACpB,EAAE,CAAC,UAAU,CAAC,mCAAmC,CAAC;QAEpD,kEAAkE;QAClE,aAAa,EAAE,QAAQ,KAAK,OAAO;QAEnC,oCAAoC;QACpC,QAAQ,EAAE,QAAQ,KAAK,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC;QAExD,mDAAmD;QACnD,cAAc,EAAE,QAAQ,KAAK,QAAQ,IAAI,aAAa,CAAC,cAAc,CAAC;KACvE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Bug-Box Filesystem Isolation
3
+ *
4
+ * Creates a structured temp directory with restrictive permissions.
5
+ * Layout:
6
+ * bugbox-XXXXX/
7
+ * ├── files/ — Read-only source snapshot (locked after population)
8
+ * ├── workspace/ — Read-write CWD for the replayed process
9
+ * └── logs/ — Read-write stdout/stderr capture
10
+ *
11
+ * Permissions:
12
+ * Linux/macOS: chmod 0700 (owner-only)
13
+ * Windows: icacls inheritance removal + current-user-only grant
14
+ */
15
+ export interface IsolatedDirResult {
16
+ /** Root of the entire Bug-Box sandbox */
17
+ rootDir: string;
18
+ /** Read-only directory for captured source files */
19
+ filesDir: string;
20
+ /** Read-write working directory (the replayed process CWD) */
21
+ workspaceDir: string;
22
+ /** Read-write directory for stdout/stderr log capture */
23
+ logsDir: string;
24
+ }
25
+ /**
26
+ * Creates a new isolated directory structure with restrictive permissions.
27
+ * Works on Linux, macOS, and Windows without requiring root/admin.
28
+ */
29
+ export declare function createIsolatedDir(): IsolatedDirResult;
30
+ /**
31
+ * Locks a directory to read-only.
32
+ * Used after populating filesDir with the source snapshot,
33
+ * so the replayed process cannot modify captured files.
34
+ *
35
+ * Linux/macOS: removes write bit (chmod a-w recursively).
36
+ * Windows: icacls to deny write.
37
+ */
38
+ export declare function lockDirReadOnly(dirPath: string): void;
39
+ /**
40
+ * Restores write permissions on a directory that was previously locked.
41
+ * Must be called before cleanup if lockDirReadOnly was used.
42
+ */
43
+ export declare function unlockDir(dirPath: string): void;
44
+ /**
45
+ * Removes the entire isolated directory.
46
+ * Handles read-only files by unlocking first.
47
+ * Never throws — best-effort cleanup.
48
+ */
49
+ export declare function cleanupIsolatedDir(result: IsolatedDirResult): void;
50
+ //# sourceMappingURL=filesystem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../../src/sandbox/filesystem.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,YAAY,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,iBAAiB,CAgBrD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAcrD;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAc/C;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAelE"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Bug-Box Filesystem Isolation
3
+ *
4
+ * Creates a structured temp directory with restrictive permissions.
5
+ * Layout:
6
+ * bugbox-XXXXX/
7
+ * ├── files/ — Read-only source snapshot (locked after population)
8
+ * ├── workspace/ — Read-write CWD for the replayed process
9
+ * └── logs/ — Read-write stdout/stderr capture
10
+ *
11
+ * Permissions:
12
+ * Linux/macOS: chmod 0700 (owner-only)
13
+ * Windows: icacls inheritance removal + current-user-only grant
14
+ */
15
+ import * as fs from 'fs';
16
+ import * as path from 'path';
17
+ import * as os from 'os';
18
+ import { spawnSync } from 'child_process';
19
+ /**
20
+ * Creates a new isolated directory structure with restrictive permissions.
21
+ * Works on Linux, macOS, and Windows without requiring root/admin.
22
+ */
23
+ export function createIsolatedDir() {
24
+ const rootDir = fs.mkdtempSync(path.join(os.tmpdir(), 'bugbox-'));
25
+ // Apply restrictive permissions to the root
26
+ applyRestrictivePermissions(rootDir);
27
+ // Create subdirectories
28
+ const filesDir = path.join(rootDir, 'files');
29
+ const workspaceDir = path.join(rootDir, 'workspace');
30
+ const logsDir = path.join(rootDir, 'logs');
31
+ fs.mkdirSync(filesDir, { recursive: true });
32
+ fs.mkdirSync(workspaceDir, { recursive: true });
33
+ fs.mkdirSync(logsDir, { recursive: true });
34
+ return { rootDir, filesDir, workspaceDir, logsDir };
35
+ }
36
+ /**
37
+ * Locks a directory to read-only.
38
+ * Used after populating filesDir with the source snapshot,
39
+ * so the replayed process cannot modify captured files.
40
+ *
41
+ * Linux/macOS: removes write bit (chmod a-w recursively).
42
+ * Windows: icacls to deny write.
43
+ */
44
+ export function lockDirReadOnly(dirPath) {
45
+ if (!fs.existsSync(dirPath))
46
+ return;
47
+ if (os.platform() === 'win32') {
48
+ // On Windows, use icacls to set read-only attribute on all files
49
+ spawnSync('icacls', [dirPath, '/deny', `${os.userInfo().username}:(W)`, '/T', '/C'], {
50
+ encoding: 'utf-8',
51
+ timeout: 10000,
52
+ stdio: 'pipe',
53
+ });
54
+ }
55
+ else {
56
+ // Unix: remove write bit recursively
57
+ setPermissionsRecursive(dirPath, 0o555, 0o444);
58
+ }
59
+ }
60
+ /**
61
+ * Restores write permissions on a directory that was previously locked.
62
+ * Must be called before cleanup if lockDirReadOnly was used.
63
+ */
64
+ export function unlockDir(dirPath) {
65
+ if (!fs.existsSync(dirPath))
66
+ return;
67
+ if (os.platform() === 'win32') {
68
+ // Remove the deny rule
69
+ spawnSync('icacls', [dirPath, '/remove:d', os.userInfo().username, '/T', '/C'], {
70
+ encoding: 'utf-8',
71
+ timeout: 10000,
72
+ stdio: 'pipe',
73
+ });
74
+ }
75
+ else {
76
+ // Unix: restore write bit
77
+ setPermissionsRecursive(dirPath, 0o755, 0o644);
78
+ }
79
+ }
80
+ /**
81
+ * Removes the entire isolated directory.
82
+ * Handles read-only files by unlocking first.
83
+ * Never throws — best-effort cleanup.
84
+ */
85
+ export function cleanupIsolatedDir(result) {
86
+ if (!fs.existsSync(result.rootDir))
87
+ return;
88
+ try {
89
+ // Unlock filesDir in case it was locked read-only
90
+ unlockDir(result.filesDir);
91
+ }
92
+ catch {
93
+ // Best effort
94
+ }
95
+ try {
96
+ fs.rmSync(result.rootDir, { recursive: true, force: true });
97
+ }
98
+ catch {
99
+ // Best effort — on Windows, locked handles may prevent immediate removal
100
+ }
101
+ }
102
+ // ── Internal helpers ──
103
+ /**
104
+ * Applies restrictive permissions to the root sandbox directory.
105
+ * Owner-only on Unix. Current-user-only ACL on Windows.
106
+ */
107
+ function applyRestrictivePermissions(dirPath) {
108
+ if (os.platform() === 'win32') {
109
+ // Remove inherited ACLs, grant full control to current user only
110
+ spawnSync('icacls', [dirPath, '/inheritance:r', '/grant:r', `${os.userInfo().username}:(OI)(CI)F`], { encoding: 'utf-8', timeout: 5000, stdio: 'pipe' });
111
+ }
112
+ else {
113
+ // Unix: 0700 — owner can read/write/execute, nobody else
114
+ fs.chmodSync(dirPath, 0o700);
115
+ }
116
+ }
117
+ /**
118
+ * Recursively sets permissions on directories and files.
119
+ * dirMode applies to directories, fileMode applies to files.
120
+ */
121
+ function setPermissionsRecursive(dirPath, dirMode, fileMode) {
122
+ fs.chmodSync(dirPath, dirMode);
123
+ const entries = fs.readdirSync(dirPath, { withFileTypes: true });
124
+ for (const entry of entries) {
125
+ const fullPath = path.join(dirPath, entry.name);
126
+ if (entry.isDirectory()) {
127
+ setPermissionsRecursive(fullPath, dirMode, fileMode);
128
+ }
129
+ else if (entry.isFile()) {
130
+ fs.chmodSync(fullPath, fileMode);
131
+ }
132
+ }
133
+ }
134
+ //# sourceMappingURL=filesystem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem.js","sourceRoot":"","sources":["../../src/sandbox/filesystem.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Bug-Box Network Isolation
3
+ *
4
+ * Provides three strategies to prevent a replayed command from accessing the network:
5
+ *
6
+ * - unshare (Linux): wraps the command in `unshare --net`, creating a new
7
+ * network namespace with only a loopback interface.
8
+ * - sandbox-exec (macOS): wraps the command in `sandbox-exec -p '(deny network*)'`.
9
+ * - netsh (Windows): creates a temporary Windows Firewall rule before the
10
+ * process starts and removes it after the process exits.
11
+ * This is a pre/post approach, not a command wrapper.
12
+ * - none: no network isolation. Used when no primitive is available,
13
+ * or when the user explicitly opts out.
14
+ *
15
+ * Design:
16
+ * selectNetworkStrategy() — picks the best strategy for the current platform.
17
+ * buildNetworkIsolationArgs() — transforms the command array (wrapping if needed).
18
+ * createNetworkCleanup() — returns a cleanup function for post-exec teardown.
19
+ */
20
+ import { PlatformCapabilities } from './capabilities';
21
+ /** The isolation approach selected for this platform. */
22
+ export type NetworkStrategy = 'unshare' | 'netsh' | 'sandbox-exec' | 'none';
23
+ /** Result of command transformation for network isolation. */
24
+ export interface NetworkIsolationResult {
25
+ /** The (possibly wrapped) command array to spawn. */
26
+ command: string[];
27
+ /** If true, the caller must run pre-exec setup (e.g. netsh rule) before spawn. */
28
+ needsPreExec: boolean;
29
+ /** The strategy that was applied. */
30
+ strategy: NetworkStrategy;
31
+ }
32
+ /**
33
+ * Selects the best available network isolation strategy for the given platform.
34
+ */
35
+ export declare function selectNetworkStrategy(caps: PlatformCapabilities): NetworkStrategy;
36
+ /**
37
+ * Transforms a command array to include network isolation, if the strategy
38
+ * supports command wrapping (unshare, sandbox-exec).
39
+ *
40
+ * For `netsh`, the command is returned unchanged because netsh uses firewall
41
+ * rules applied before/after the process, not a wrapper.
42
+ *
43
+ * For `none`, the command is returned unchanged.
44
+ */
45
+ export declare function buildNetworkIsolationArgs(strategy: NetworkStrategy, command: string[]): NetworkIsolationResult;
46
+ /**
47
+ * Creates a cleanup function that removes any network isolation artifacts
48
+ * after the replayed process exits.
49
+ *
50
+ * - unshare / sandbox-exec: the kernel automatically tears down the namespace
51
+ * or sandbox when the process exits. Cleanup is a no-op.
52
+ * - netsh: removes the temporary firewall rule by name.
53
+ * - none: no-op.
54
+ *
55
+ * @param strategy The isolation strategy that was applied.
56
+ * @param ruleName (netsh only) The firewall rule name to remove.
57
+ */
58
+ export declare function createNetworkCleanup(strategy: NetworkStrategy, ruleName?: string): () => void;
59
+ /**
60
+ * Adds a Windows Firewall rule that blocks all outbound traffic for a process.
61
+ * Called as pre-exec for the `netsh` strategy.
62
+ *
63
+ * @param ruleName Unique rule name for later cleanup.
64
+ * @param exePath Path to the executable to block.
65
+ * @returns true if the rule was added, false on failure.
66
+ */
67
+ export declare function addFirewallBlockRule(ruleName: string, exePath: string): boolean;
68
+ //# sourceMappingURL=network.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../src/sandbox/network.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAGtD,yDAAyD;AACzD,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,OAAO,GAAG,cAAc,GAAG,MAAM,CAAC;AAE5E,8DAA8D;AAC9D,MAAM,WAAW,sBAAsB;IACrC,qDAAqD;IACrD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,kFAAkF;IAClF,YAAY,EAAE,OAAO,CAAC;IACtB,qCAAqC;IACrC,QAAQ,EAAE,eAAe,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,oBAAoB,GAAG,eAAe,CAWjF;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,MAAM,EAAE,GAChB,sBAAsB,CA4CxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,IAAI,CAiBZ;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAiB/E"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Bug-Box Network Isolation
3
+ *
4
+ * Provides three strategies to prevent a replayed command from accessing the network:
5
+ *
6
+ * - unshare (Linux): wraps the command in `unshare --net`, creating a new
7
+ * network namespace with only a loopback interface.
8
+ * - sandbox-exec (macOS): wraps the command in `sandbox-exec -p '(deny network*)'`.
9
+ * - netsh (Windows): creates a temporary Windows Firewall rule before the
10
+ * process starts and removes it after the process exits.
11
+ * This is a pre/post approach, not a command wrapper.
12
+ * - none: no network isolation. Used when no primitive is available,
13
+ * or when the user explicitly opts out.
14
+ *
15
+ * Design:
16
+ * selectNetworkStrategy() — picks the best strategy for the current platform.
17
+ * buildNetworkIsolationArgs() — transforms the command array (wrapping if needed).
18
+ * createNetworkCleanup() — returns a cleanup function for post-exec teardown.
19
+ */
20
+ import { spawnSync } from 'child_process';
21
+ /**
22
+ * Selects the best available network isolation strategy for the given platform.
23
+ */
24
+ export function selectNetworkStrategy(caps) {
25
+ switch (caps.platform) {
26
+ case 'linux':
27
+ return caps.hasUnshare ? 'unshare' : 'none';
28
+ case 'win32':
29
+ return caps.hasNetsh ? 'netsh' : 'none';
30
+ case 'darwin':
31
+ return caps.hasSandboxExec ? 'sandbox-exec' : 'none';
32
+ default:
33
+ return 'none';
34
+ }
35
+ }
36
+ /**
37
+ * Transforms a command array to include network isolation, if the strategy
38
+ * supports command wrapping (unshare, sandbox-exec).
39
+ *
40
+ * For `netsh`, the command is returned unchanged because netsh uses firewall
41
+ * rules applied before/after the process, not a wrapper.
42
+ *
43
+ * For `none`, the command is returned unchanged.
44
+ */
45
+ export function buildNetworkIsolationArgs(strategy, command) {
46
+ switch (strategy) {
47
+ case 'unshare':
48
+ return {
49
+ // unshare --net creates a new network namespace with only loopback.
50
+ // --map-root-user allows it to work without root (user namespace).
51
+ command: ['unshare', '--net', '--map-root-user', '--', ...command],
52
+ needsPreExec: false,
53
+ strategy,
54
+ };
55
+ case 'sandbox-exec':
56
+ return {
57
+ // sandbox-exec with a deny-network profile.
58
+ // The profile denies all network operations; the process can still
59
+ // use local filesystem and IPC.
60
+ command: [
61
+ 'sandbox-exec',
62
+ '-p',
63
+ '(version 1)(allow default)(deny network*)',
64
+ '--',
65
+ ...command,
66
+ ],
67
+ needsPreExec: false,
68
+ strategy,
69
+ };
70
+ case 'netsh':
71
+ // netsh doesn't wrap the command. The caller must call pre-exec setup
72
+ // (addFirewallBlockRule) and post-exec cleanup (removeFirewallBlockRule).
73
+ return {
74
+ command,
75
+ needsPreExec: true,
76
+ strategy,
77
+ };
78
+ case 'none':
79
+ default:
80
+ return {
81
+ command,
82
+ needsPreExec: false,
83
+ strategy,
84
+ };
85
+ }
86
+ }
87
+ /**
88
+ * Creates a cleanup function that removes any network isolation artifacts
89
+ * after the replayed process exits.
90
+ *
91
+ * - unshare / sandbox-exec: the kernel automatically tears down the namespace
92
+ * or sandbox when the process exits. Cleanup is a no-op.
93
+ * - netsh: removes the temporary firewall rule by name.
94
+ * - none: no-op.
95
+ *
96
+ * @param strategy The isolation strategy that was applied.
97
+ * @param ruleName (netsh only) The firewall rule name to remove.
98
+ */
99
+ export function createNetworkCleanup(strategy, ruleName) {
100
+ if (strategy === 'netsh' && ruleName) {
101
+ return () => {
102
+ try {
103
+ spawnSync('netsh', ['advfirewall', 'firewall', 'delete', 'rule', `name=${ruleName}`], { encoding: 'utf-8', timeout: 5000, stdio: 'pipe' });
104
+ }
105
+ catch {
106
+ // Best effort — rule may not exist or we lack permissions
107
+ }
108
+ };
109
+ }
110
+ // All other strategies: kernel cleans up automatically, or nothing was applied
111
+ return () => { };
112
+ }
113
+ /**
114
+ * Adds a Windows Firewall rule that blocks all outbound traffic for a process.
115
+ * Called as pre-exec for the `netsh` strategy.
116
+ *
117
+ * @param ruleName Unique rule name for later cleanup.
118
+ * @param exePath Path to the executable to block.
119
+ * @returns true if the rule was added, false on failure.
120
+ */
121
+ export function addFirewallBlockRule(ruleName, exePath) {
122
+ try {
123
+ const result = spawnSync('netsh', [
124
+ 'advfirewall', 'firewall', 'add', 'rule',
125
+ `name=${ruleName}`,
126
+ 'dir=out',
127
+ 'action=block',
128
+ `program=${exePath}`,
129
+ ], { encoding: 'utf-8', timeout: 5000, stdio: 'pipe' });
130
+ return result.status === 0;
131
+ }
132
+ catch {
133
+ return false;
134
+ }
135
+ }
136
+ //# sourceMappingURL=network.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network.js","sourceRoot":"","sources":["../../src/sandbox/network.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAe1C;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAA0B;IAC9D,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;QACtB,KAAK,OAAO;YACV,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;QAC9C,KAAK,OAAO;YACV,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QAC1C,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC;QACvD;YACE,OAAO,MAAM,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB,CACvC,QAAyB,EACzB,OAAiB;IAEjB,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,SAAS;YACZ,OAAO;gBACL,oEAAoE;gBACpE,mEAAmE;gBACnE,OAAO,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;gBAClE,YAAY,EAAE,KAAK;gBACnB,QAAQ;aACT,CAAC;QAEJ,KAAK,cAAc;YACjB,OAAO;gBACL,4CAA4C;gBAC5C,mEAAmE;gBACnE,gCAAgC;gBAChC,OAAO,EAAE;oBACP,cAAc;oBACd,IAAI;oBACJ,2CAA2C;oBAC3C,IAAI;oBACJ,GAAG,OAAO;iBACX;gBACD,YAAY,EAAE,KAAK;gBACnB,QAAQ;aACT,CAAC;QAEJ,KAAK,OAAO;YACV,sEAAsE;YACtE,0EAA0E;YAC1E,OAAO;gBACL,OAAO;gBACP,YAAY,EAAE,IAAI;gBAClB,QAAQ;aACT,CAAC;QAEJ,KAAK,MAAM,CAAC;QACZ;YACE,OAAO;gBACL,OAAO;gBACP,YAAY,EAAE,KAAK;gBACnB,QAAQ;aACT,CAAC;IACN,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAAyB,EACzB,QAAiB;IAEjB,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,EAAE,CAAC;QACrC,OAAO,GAAG,EAAE;YACV,IAAI,CAAC;gBACH,SAAS,CACP,OAAO,EACP,CAAC,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,QAAQ,EAAE,CAAC,EACjE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CACpD,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,0DAA0D;YAC5D,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;IAED,+EAA+E;IAC/E,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;AAClB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAgB,EAAE,OAAe;IACpE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,SAAS,CACtB,OAAO,EACP;YACE,aAAa,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM;YACxC,QAAQ,QAAQ,EAAE;YAClB,SAAS;YACT,cAAc;YACd,WAAW,OAAO,EAAE;SACrB,EACD,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CACpD,CAAC;QACF,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Bug-Box Process Isolation
3
+ *
4
+ * Provides OS-level process namespace isolation so the replayed command
5
+ * cannot see or signal host processes.
6
+ */
7
+ import { PlatformCapabilities } from './capabilities';
8
+ export type ProcessStrategy = 'unshare' | 'none';
9
+ /**
10
+ * Selects the best available process isolation strategy based on capabilities.
11
+ */
12
+ export declare function selectProcessStrategy(caps: PlatformCapabilities): ProcessStrategy;
13
+ /**
14
+ * Modifies the command array to run within a new process namespace.
15
+ */
16
+ export declare function buildProcessIsolationArgs(strategy: ProcessStrategy, command: string[]): string[];
17
+ //# sourceMappingURL=process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/sandbox/process.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEtD,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,MAAM,CAAC;AAEjD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,oBAAoB,GAAG,eAAe,CAQjF;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAShG"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Bug-Box Process Isolation
3
+ *
4
+ * Provides OS-level process namespace isolation so the replayed command
5
+ * cannot see or signal host processes.
6
+ */
7
+ /**
8
+ * Selects the best available process isolation strategy based on capabilities.
9
+ */
10
+ export function selectProcessStrategy(caps) {
11
+ if (caps.platform === 'linux' && caps.hasUnshare) {
12
+ return 'unshare';
13
+ }
14
+ // Windows Job Objects provide resource limits but not true PID namespace hiding.
15
+ // We handle Windows Job Objects in the resources layer instead.
16
+ return 'none';
17
+ }
18
+ /**
19
+ * Modifies the command array to run within a new process namespace.
20
+ */
21
+ export function buildProcessIsolationArgs(strategy, command) {
22
+ if (strategy === 'unshare') {
23
+ // --pid: create new PID namespace
24
+ // --fork: fork the new process (required for --pid)
25
+ // --mount-proc: mount a new /proc filesystem so tools like `ps` work correctly
26
+ return ['unshare', '--pid', '--fork', '--mount-proc', '--', ...command];
27
+ }
28
+ return command;
29
+ }
30
+ //# sourceMappingURL=process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/sandbox/process.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAA0B;IAC9D,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACjD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,iFAAiF;IACjF,gEAAgE;IAChE,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,QAAyB,EAAE,OAAiB;IACpF,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,kCAAkC;QAClC,oDAAoD;QACpD,+EAA+E;QAC/E,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Bug-Box Resource Isolation
3
+ *
4
+ * Provides resource limits (memory, CPU) for the replayed process
5
+ * using cgroups v2 on Linux and Job Objects on Windows.
6
+ */
7
+ import { PlatformCapabilities } from './capabilities';
8
+ export type ResourceStrategy = 'cgroups' | 'job-object' | 'none';
9
+ export interface ResourceLimits {
10
+ maxMemoryMB?: number;
11
+ maxCpuPercent?: number;
12
+ }
13
+ /**
14
+ * Selects the best available resource isolation strategy based on capabilities.
15
+ */
16
+ export declare function selectResourceStrategy(caps: PlatformCapabilities): ResourceStrategy;
17
+ /**
18
+ * Modifies the command array to apply resource limits.
19
+ */
20
+ export declare function buildResourceIsolationArgs(strategy: ResourceStrategy, command: string[], limits: ResourceLimits): string[];
21
+ //# sourceMappingURL=resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../../src/sandbox/resources.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEtD,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,YAAY,GAAG,MAAM,CAAC;AAEjE,MAAM,WAAW,cAAc;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,oBAAoB,GAAG,gBAAgB,CAUnF;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,MAAM,EAAE,EACjB,MAAM,EAAE,cAAc,GACrB,MAAM,EAAE,CA8CV"}