@carderne/sandbox-runtime 0.0.40

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 (83) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +684 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +163 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/index.d.ts +11 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +9 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/sandbox/generate-seccomp-filter.d.ts +71 -0
  12. package/dist/sandbox/generate-seccomp-filter.d.ts.map +1 -0
  13. package/dist/sandbox/generate-seccomp-filter.js +263 -0
  14. package/dist/sandbox/generate-seccomp-filter.js.map +1 -0
  15. package/dist/sandbox/http-proxy.d.ts +13 -0
  16. package/dist/sandbox/http-proxy.d.ts.map +1 -0
  17. package/dist/sandbox/http-proxy.js +217 -0
  18. package/dist/sandbox/http-proxy.js.map +1 -0
  19. package/dist/sandbox/linux-sandbox-utils.d.ts +158 -0
  20. package/dist/sandbox/linux-sandbox-utils.d.ts.map +1 -0
  21. package/dist/sandbox/linux-sandbox-utils.js +875 -0
  22. package/dist/sandbox/linux-sandbox-utils.js.map +1 -0
  23. package/dist/sandbox/macos-sandbox-utils.d.ts +40 -0
  24. package/dist/sandbox/macos-sandbox-utils.d.ts.map +1 -0
  25. package/dist/sandbox/macos-sandbox-utils.js +623 -0
  26. package/dist/sandbox/macos-sandbox-utils.js.map +1 -0
  27. package/dist/sandbox/sandbox-config.d.ts +288 -0
  28. package/dist/sandbox/sandbox-config.d.ts.map +1 -0
  29. package/dist/sandbox/sandbox-config.js +178 -0
  30. package/dist/sandbox/sandbox-config.js.map +1 -0
  31. package/dist/sandbox/sandbox-manager.d.ts +42 -0
  32. package/dist/sandbox/sandbox-manager.d.ts.map +1 -0
  33. package/dist/sandbox/sandbox-manager.js +786 -0
  34. package/dist/sandbox/sandbox-manager.js.map +1 -0
  35. package/dist/sandbox/sandbox-schemas.d.ts +57 -0
  36. package/dist/sandbox/sandbox-schemas.d.ts.map +1 -0
  37. package/dist/sandbox/sandbox-schemas.js +3 -0
  38. package/dist/sandbox/sandbox-schemas.js.map +1 -0
  39. package/dist/sandbox/sandbox-utils.d.ts +109 -0
  40. package/dist/sandbox/sandbox-utils.d.ts.map +1 -0
  41. package/dist/sandbox/sandbox-utils.js +429 -0
  42. package/dist/sandbox/sandbox-utils.js.map +1 -0
  43. package/dist/sandbox/sandbox-violation-store.d.ts +19 -0
  44. package/dist/sandbox/sandbox-violation-store.d.ts.map +1 -0
  45. package/dist/sandbox/sandbox-violation-store.js +54 -0
  46. package/dist/sandbox/sandbox-violation-store.js.map +1 -0
  47. package/dist/sandbox/socks-proxy.d.ts +13 -0
  48. package/dist/sandbox/socks-proxy.d.ts.map +1 -0
  49. package/dist/sandbox/socks-proxy.js +95 -0
  50. package/dist/sandbox/socks-proxy.js.map +1 -0
  51. package/dist/utils/config-loader.d.ts +11 -0
  52. package/dist/utils/config-loader.d.ts.map +1 -0
  53. package/dist/utils/config-loader.js +60 -0
  54. package/dist/utils/config-loader.js.map +1 -0
  55. package/dist/utils/debug.d.ts +7 -0
  56. package/dist/utils/debug.d.ts.map +1 -0
  57. package/dist/utils/debug.js +25 -0
  58. package/dist/utils/debug.js.map +1 -0
  59. package/dist/utils/platform.d.ts +15 -0
  60. package/dist/utils/platform.d.ts.map +1 -0
  61. package/dist/utils/platform.js +49 -0
  62. package/dist/utils/platform.js.map +1 -0
  63. package/dist/utils/ripgrep.d.ts +20 -0
  64. package/dist/utils/ripgrep.d.ts.map +1 -0
  65. package/dist/utils/ripgrep.js +42 -0
  66. package/dist/utils/ripgrep.js.map +1 -0
  67. package/dist/utils/which.d.ts +9 -0
  68. package/dist/utils/which.d.ts.map +1 -0
  69. package/dist/utils/which.js +25 -0
  70. package/dist/utils/which.js.map +1 -0
  71. package/dist/vendor/seccomp/arm64/apply-seccomp +0 -0
  72. package/dist/vendor/seccomp/arm64/unix-block.bpf +0 -0
  73. package/dist/vendor/seccomp/x64/apply-seccomp +0 -0
  74. package/dist/vendor/seccomp/x64/unix-block.bpf +0 -0
  75. package/dist/vendor/seccomp-src/apply-seccomp.c +98 -0
  76. package/dist/vendor/seccomp-src/seccomp-unix-block.c +97 -0
  77. package/package.json +88 -0
  78. package/vendor/seccomp/arm64/apply-seccomp +0 -0
  79. package/vendor/seccomp/arm64/unix-block.bpf +0 -0
  80. package/vendor/seccomp/x64/apply-seccomp +0 -0
  81. package/vendor/seccomp/x64/unix-block.bpf +0 -0
  82. package/vendor/seccomp-src/apply-seccomp.c +98 -0
  83. package/vendor/seccomp-src/seccomp-unix-block.c +97 -0
@@ -0,0 +1,623 @@
1
+ import shellquote from 'shell-quote';
2
+ import { spawn } from 'child_process';
3
+ import * as path from 'path';
4
+ import { logForDebugging } from '../utils/debug.js';
5
+ import { whichSync } from '../utils/which.js';
6
+ import { normalizePathForSandbox, generateProxyEnvVars, encodeSandboxedCommand, decodeSandboxedCommand, containsGlobChars, globToRegex, DANGEROUS_FILES, getDangerousDirectories, } from './sandbox-utils.js';
7
+ /**
8
+ * Get mandatory deny patterns as glob patterns (no filesystem scanning).
9
+ * macOS sandbox profile supports regex/glob matching directly via globToRegex().
10
+ */
11
+ export function macGetMandatoryDenyPatterns(allowGitConfig = false) {
12
+ const cwd = process.cwd();
13
+ const denyPaths = [];
14
+ // Dangerous files - static paths in CWD + glob patterns for subtree
15
+ for (const fileName of DANGEROUS_FILES) {
16
+ denyPaths.push(path.resolve(cwd, fileName));
17
+ denyPaths.push(`**/${fileName}`);
18
+ }
19
+ // Dangerous directories
20
+ for (const dirName of getDangerousDirectories()) {
21
+ denyPaths.push(path.resolve(cwd, dirName));
22
+ denyPaths.push(`**/${dirName}/**`);
23
+ }
24
+ // Git hooks are always blocked for security
25
+ denyPaths.push(path.resolve(cwd, '.git/hooks'));
26
+ denyPaths.push('**/.git/hooks/**');
27
+ // Git config - conditionally blocked based on allowGitConfig setting
28
+ if (!allowGitConfig) {
29
+ denyPaths.push(path.resolve(cwd, '.git/config'));
30
+ denyPaths.push('**/.git/config');
31
+ }
32
+ return [...new Set(denyPaths)];
33
+ }
34
+ const sessionSuffix = `_${Math.random().toString(36).slice(2, 11)}_SBX`;
35
+ /**
36
+ * Generate a unique log tag for sandbox monitoring
37
+ * @param command - The command being executed (will be base64 encoded)
38
+ */
39
+ function generateLogTag(command) {
40
+ const encodedCommand = encodeSandboxedCommand(command);
41
+ return `CMD64_${encodedCommand}_END_${sessionSuffix}`;
42
+ }
43
+ /**
44
+ * Get all ancestor directories for a path, up to (but not including) root
45
+ * Example: /private/tmp/test/file.txt -> ["/private/tmp/test", "/private/tmp", "/private"]
46
+ */
47
+ function getAncestorDirectories(pathStr) {
48
+ const ancestors = [];
49
+ let currentPath = path.dirname(pathStr);
50
+ // Walk up the directory tree until we reach root
51
+ while (currentPath !== '/' && currentPath !== '.') {
52
+ ancestors.push(currentPath);
53
+ const parentPath = path.dirname(currentPath);
54
+ // Break if we've reached the top (path.dirname returns the same path for root)
55
+ if (parentPath === currentPath) {
56
+ break;
57
+ }
58
+ currentPath = parentPath;
59
+ }
60
+ return ancestors;
61
+ }
62
+ /**
63
+ * Generate deny rules for file movement (file-write-unlink) to protect paths
64
+ * This prevents bypassing read or write restrictions by moving files/directories
65
+ *
66
+ * @param pathPatterns - Array of path patterns to protect (can include globs)
67
+ * @param logTag - Log tag for sandbox violations
68
+ * @returns Array of sandbox profile rule lines
69
+ */
70
+ function generateMoveBlockingRules(pathPatterns, logTag) {
71
+ const rules = [];
72
+ for (const pathPattern of pathPatterns) {
73
+ const normalizedPath = normalizePathForSandbox(pathPattern);
74
+ if (containsGlobChars(normalizedPath)) {
75
+ // Use regex matching for glob patterns
76
+ const regexPattern = globToRegex(normalizedPath);
77
+ // Block moving/renaming files matching this pattern
78
+ rules.push(`(deny file-write-unlink`, ` (regex ${escapePath(regexPattern)})`, ` (with message "${logTag}"))`);
79
+ // For glob patterns, extract the static prefix and block ancestor moves
80
+ // Remove glob characters to get the directory prefix
81
+ const staticPrefix = normalizedPath.split(/[*?[\]]/)[0];
82
+ if (staticPrefix && staticPrefix !== '/') {
83
+ // Get the directory containing the glob pattern
84
+ const baseDir = staticPrefix.endsWith('/')
85
+ ? staticPrefix.slice(0, -1)
86
+ : path.dirname(staticPrefix);
87
+ // Block moves of the base directory itself
88
+ rules.push(`(deny file-write-unlink`, ` (literal ${escapePath(baseDir)})`, ` (with message "${logTag}"))`);
89
+ // Block moves of ancestor directories
90
+ for (const ancestorDir of getAncestorDirectories(baseDir)) {
91
+ rules.push(`(deny file-write-unlink`, ` (literal ${escapePath(ancestorDir)})`, ` (with message "${logTag}"))`);
92
+ }
93
+ }
94
+ }
95
+ else {
96
+ // Use subpath matching for literal paths
97
+ // Block moving/renaming the denied path itself
98
+ rules.push(`(deny file-write-unlink`, ` (subpath ${escapePath(normalizedPath)})`, ` (with message "${logTag}"))`);
99
+ // Block moves of ancestor directories
100
+ for (const ancestorDir of getAncestorDirectories(normalizedPath)) {
101
+ rules.push(`(deny file-write-unlink`, ` (literal ${escapePath(ancestorDir)})`, ` (with message "${logTag}"))`);
102
+ }
103
+ }
104
+ }
105
+ return rules;
106
+ }
107
+ /**
108
+ * Generate filesystem read rules for sandbox profile
109
+ *
110
+ * Supports two layers:
111
+ * 1. denyOnly: deny reads from these paths (broad regions like /Users)
112
+ * 2. allowWithinDeny: re-allow reads within denied regions (like CWD)
113
+ * allowWithinDeny takes precedence over denyOnly.
114
+ *
115
+ * In Seatbelt profiles, later rules take precedence, so we emit:
116
+ * (allow file-read*) ← default: allow everything
117
+ * (deny file-read* ...) ← deny broad regions
118
+ * (allow file-read* ...) ← re-allow specific paths within denied regions
119
+ */
120
+ function generateReadRules(config, logTag) {
121
+ if (!config) {
122
+ return [`(allow file-read*)`];
123
+ }
124
+ const rules = [];
125
+ // Start by allowing everything
126
+ rules.push(`(allow file-read*)`);
127
+ // Then deny specific paths
128
+ for (const pathPattern of config.denyOnly || []) {
129
+ const normalizedPath = normalizePathForSandbox(pathPattern);
130
+ if (containsGlobChars(normalizedPath)) {
131
+ // Use regex matching for glob patterns
132
+ const regexPattern = globToRegex(normalizedPath);
133
+ rules.push(`(deny file-read*`, ` (regex ${escapePath(regexPattern)})`, ` (with message "${logTag}"))`);
134
+ }
135
+ else {
136
+ // Use subpath matching for literal paths
137
+ rules.push(`(deny file-read*`, ` (subpath ${escapePath(normalizedPath)})`, ` (with message "${logTag}"))`);
138
+ }
139
+ }
140
+ // Re-allow specific paths within denied regions (allowWithinDeny takes precedence)
141
+ for (const pathPattern of config.allowWithinDeny || []) {
142
+ const normalizedPath = normalizePathForSandbox(pathPattern);
143
+ if (containsGlobChars(normalizedPath)) {
144
+ const regexPattern = globToRegex(normalizedPath);
145
+ rules.push(`(allow file-read*`, ` (regex ${escapePath(regexPattern)})`, ` (with message "${logTag}"))`);
146
+ }
147
+ else {
148
+ rules.push(`(allow file-read*`, ` (subpath ${escapePath(normalizedPath)})`, ` (with message "${logTag}"))`);
149
+ }
150
+ }
151
+ // Block file movement to prevent bypass via mv/rename
152
+ rules.push(...generateMoveBlockingRules(config.denyOnly || [], logTag));
153
+ return rules;
154
+ }
155
+ /**
156
+ * Generate filesystem write rules for sandbox profile
157
+ */
158
+ function generateWriteRules(config, logTag, allowGitConfig = false) {
159
+ if (!config) {
160
+ return [`(allow file-write*)`];
161
+ }
162
+ const rules = [];
163
+ // Automatically allow TMPDIR parent on macOS when write restrictions are enabled
164
+ const tmpdirParents = getTmpdirParentIfMacOSPattern();
165
+ for (const tmpdirParent of tmpdirParents) {
166
+ const normalizedPath = normalizePathForSandbox(tmpdirParent);
167
+ rules.push(`(allow file-write*`, ` (subpath ${escapePath(normalizedPath)})`, ` (with message "${logTag}"))`);
168
+ }
169
+ // Generate allow rules
170
+ for (const pathPattern of config.allowOnly || []) {
171
+ const normalizedPath = normalizePathForSandbox(pathPattern);
172
+ if (containsGlobChars(normalizedPath)) {
173
+ // Use regex matching for glob patterns
174
+ const regexPattern = globToRegex(normalizedPath);
175
+ rules.push(`(allow file-write*`, ` (regex ${escapePath(regexPattern)})`, ` (with message "${logTag}"))`);
176
+ }
177
+ else {
178
+ // Use subpath matching for literal paths
179
+ rules.push(`(allow file-write*`, ` (subpath ${escapePath(normalizedPath)})`, ` (with message "${logTag}"))`);
180
+ }
181
+ }
182
+ // Combine user-specified and mandatory deny patterns (no ripgrep needed on macOS)
183
+ const denyPaths = [
184
+ ...(config.denyWithinAllow || []),
185
+ ...macGetMandatoryDenyPatterns(allowGitConfig),
186
+ ];
187
+ for (const pathPattern of denyPaths) {
188
+ const normalizedPath = normalizePathForSandbox(pathPattern);
189
+ if (containsGlobChars(normalizedPath)) {
190
+ // Use regex matching for glob patterns
191
+ const regexPattern = globToRegex(normalizedPath);
192
+ rules.push(`(deny file-write*`, ` (regex ${escapePath(regexPattern)})`, ` (with message "${logTag}"))`);
193
+ }
194
+ else {
195
+ // Use subpath matching for literal paths
196
+ rules.push(`(deny file-write*`, ` (subpath ${escapePath(normalizedPath)})`, ` (with message "${logTag}"))`);
197
+ }
198
+ }
199
+ // Block file movement to prevent bypass via mv/rename
200
+ rules.push(...generateMoveBlockingRules(denyPaths, logTag));
201
+ return rules;
202
+ }
203
+ /**
204
+ * Generate complete sandbox profile
205
+ */
206
+ function generateSandboxProfile({ readConfig, writeConfig, httpProxyPort, socksProxyPort, needsNetworkRestriction, allowUnixSockets, allowAllUnixSockets, allowLocalBinding, allowPty, allowGitConfig = false, enableWeakerNetworkIsolation = false, logTag, }) {
207
+ const profile = [
208
+ '(version 1)',
209
+ `(deny default (with message "${logTag}"))`,
210
+ '',
211
+ `; LogTag: ${logTag}`,
212
+ '',
213
+ '; Essential permissions - based on Chrome sandbox policy',
214
+ '; Process permissions',
215
+ '(allow process-exec)',
216
+ '(allow process-fork)',
217
+ '(allow process-info* (target same-sandbox))',
218
+ '(allow signal (target same-sandbox))',
219
+ '(allow mach-priv-task-port (target same-sandbox))',
220
+ '',
221
+ '; User preferences',
222
+ '(allow user-preference-read)',
223
+ '',
224
+ '; Mach IPC - specific services only (no wildcard)',
225
+ '(allow mach-lookup',
226
+ ' (global-name "com.apple.audio.systemsoundserver")',
227
+ ' (global-name "com.apple.distributed_notifications@Uv3")',
228
+ ' (global-name "com.apple.FontObjectsServer")',
229
+ ' (global-name "com.apple.fonts")',
230
+ ' (global-name "com.apple.logd")',
231
+ ' (global-name "com.apple.lsd.mapdb")',
232
+ ' (global-name "com.apple.PowerManagement.control")',
233
+ ' (global-name "com.apple.system.logger")',
234
+ ' (global-name "com.apple.system.notification_center")',
235
+ ' (global-name "com.apple.system.opendirectoryd.libinfo")',
236
+ ' (global-name "com.apple.system.opendirectoryd.membership")',
237
+ ' (global-name "com.apple.bsd.dirhelper")',
238
+ ' (global-name "com.apple.securityd.xpc")',
239
+ ' (global-name "com.apple.coreservices.launchservicesd")',
240
+ ')',
241
+ '',
242
+ ...(enableWeakerNetworkIsolation
243
+ ? [
244
+ '; trustd.agent - needed for Go TLS certificate verification (weaker network isolation)',
245
+ '(allow mach-lookup (global-name "com.apple.trustd.agent"))',
246
+ '; configd - needed for Rust/Go programs that query system proxy/network config (uv, cargo)',
247
+ '(allow mach-lookup (global-name "com.apple.SystemConfiguration.configd"))',
248
+ ]
249
+ : []),
250
+ '',
251
+ '; POSIX IPC - shared memory',
252
+ '(allow ipc-posix-shm)',
253
+ '',
254
+ '; POSIX IPC - semaphores for Python multiprocessing',
255
+ '(allow ipc-posix-sem)',
256
+ '',
257
+ '; IOKit - specific operations only',
258
+ '(allow iokit-open',
259
+ ' (iokit-registry-entry-class "IOSurfaceRootUserClient")',
260
+ ' (iokit-registry-entry-class "RootDomainUserClient")',
261
+ ' (iokit-user-client-class "IOSurfaceSendRight")',
262
+ ')',
263
+ '',
264
+ '; IOKit properties',
265
+ '(allow iokit-get-properties)',
266
+ '',
267
+ "; Specific safe system-sockets, doesn't allow network access",
268
+ '(allow system-socket (require-all (socket-domain AF_SYSTEM) (socket-protocol 2)))',
269
+ '',
270
+ '; sysctl - specific sysctls only',
271
+ '(allow sysctl-read',
272
+ ' (sysctl-name "hw.activecpu")',
273
+ ' (sysctl-name "hw.busfrequency_compat")',
274
+ ' (sysctl-name "hw.byteorder")',
275
+ ' (sysctl-name "hw.cacheconfig")',
276
+ ' (sysctl-name "hw.cachelinesize_compat")',
277
+ ' (sysctl-name "hw.cpufamily")',
278
+ ' (sysctl-name "hw.cpufrequency")',
279
+ ' (sysctl-name "hw.cpufrequency_compat")',
280
+ ' (sysctl-name "hw.cputype")',
281
+ ' (sysctl-name "hw.l1dcachesize_compat")',
282
+ ' (sysctl-name "hw.l1icachesize_compat")',
283
+ ' (sysctl-name "hw.l2cachesize_compat")',
284
+ ' (sysctl-name "hw.l3cachesize_compat")',
285
+ ' (sysctl-name "hw.logicalcpu")',
286
+ ' (sysctl-name "hw.logicalcpu_max")',
287
+ ' (sysctl-name "hw.machine")',
288
+ ' (sysctl-name "hw.memsize")',
289
+ ' (sysctl-name "hw.ncpu")',
290
+ ' (sysctl-name "hw.nperflevels")',
291
+ ' (sysctl-name "hw.packages")',
292
+ ' (sysctl-name "hw.pagesize_compat")',
293
+ ' (sysctl-name "hw.pagesize")',
294
+ ' (sysctl-name "hw.physicalcpu")',
295
+ ' (sysctl-name "hw.physicalcpu_max")',
296
+ ' (sysctl-name "hw.tbfrequency_compat")',
297
+ ' (sysctl-name "hw.vectorunit")',
298
+ ' (sysctl-name "kern.argmax")',
299
+ ' (sysctl-name "kern.bootargs")',
300
+ ' (sysctl-name "kern.hostname")',
301
+ ' (sysctl-name "kern.maxfiles")',
302
+ ' (sysctl-name "kern.maxfilesperproc")',
303
+ ' (sysctl-name "kern.maxproc")',
304
+ ' (sysctl-name "kern.ngroups")',
305
+ ' (sysctl-name "kern.osproductversion")',
306
+ ' (sysctl-name "kern.osrelease")',
307
+ ' (sysctl-name "kern.ostype")',
308
+ ' (sysctl-name "kern.osvariant_status")',
309
+ ' (sysctl-name "kern.osversion")',
310
+ ' (sysctl-name "kern.secure_kernel")',
311
+ ' (sysctl-name "kern.tcsm_available")',
312
+ ' (sysctl-name "kern.tcsm_enable")',
313
+ ' (sysctl-name "kern.usrstack64")',
314
+ ' (sysctl-name "kern.version")',
315
+ ' (sysctl-name "kern.willshutdown")',
316
+ ' (sysctl-name "machdep.cpu.brand_string")',
317
+ ' (sysctl-name "machdep.ptrauth_enabled")',
318
+ ' (sysctl-name "security.mac.lockdown_mode_state")',
319
+ ' (sysctl-name "sysctl.proc_cputype")',
320
+ ' (sysctl-name "vm.loadavg")',
321
+ ' (sysctl-name-prefix "hw.optional.arm")',
322
+ ' (sysctl-name-prefix "hw.optional.arm.")',
323
+ ' (sysctl-name-prefix "hw.optional.armv8_")',
324
+ ' (sysctl-name-prefix "hw.perflevel")',
325
+ ' (sysctl-name-prefix "kern.proc.all")',
326
+ ' (sysctl-name-prefix "kern.proc.pgrp.")',
327
+ ' (sysctl-name-prefix "kern.proc.pid.")',
328
+ ' (sysctl-name-prefix "machdep.cpu.")',
329
+ ' (sysctl-name-prefix "net.routetable.")',
330
+ ')',
331
+ '',
332
+ '; V8 thread calculations',
333
+ '(allow sysctl-write',
334
+ ' (sysctl-name "kern.tcsm_enable")',
335
+ ')',
336
+ '',
337
+ '; Distributed notifications',
338
+ '(allow distributed-notification-post)',
339
+ '',
340
+ '; Specific mach-lookup permissions for security operations',
341
+ '(allow mach-lookup (global-name "com.apple.SecurityServer"))',
342
+ '',
343
+ '; File I/O on device files',
344
+ '(allow file-ioctl (literal "/dev/null"))',
345
+ '(allow file-ioctl (literal "/dev/zero"))',
346
+ '(allow file-ioctl (literal "/dev/random"))',
347
+ '(allow file-ioctl (literal "/dev/urandom"))',
348
+ '(allow file-ioctl (literal "/dev/dtracehelper"))',
349
+ '(allow file-ioctl (literal "/dev/tty"))',
350
+ '',
351
+ '(allow file-ioctl file-read-data file-write-data',
352
+ ' (require-all',
353
+ ' (literal "/dev/null")',
354
+ ' (vnode-type CHARACTER-DEVICE)',
355
+ ' )',
356
+ ')',
357
+ '',
358
+ ];
359
+ // Network rules
360
+ profile.push('; Network');
361
+ if (!needsNetworkRestriction) {
362
+ profile.push('(allow network*)');
363
+ }
364
+ else {
365
+ // Allow local binding if requested
366
+ // Use "*:*" instead of "localhost:*" because modern runtimes (Java, etc.) create
367
+ // IPv6 dual-stack sockets by default. When binding such a socket to 127.0.0.1,
368
+ // the kernel represents it as ::ffff:127.0.0.1 (IPv4-mapped IPv6). Seatbelt's
369
+ // "localhost" filter only matches 127.0.0.1 and ::1, NOT ::ffff:127.0.0.1.
370
+ // Using (local ip "*:*") is safe because it only matches the LOCAL endpoint —
371
+ // internet-bound connections originate from non-loopback interfaces, so they
372
+ // remain blocked by (deny default).
373
+ if (allowLocalBinding) {
374
+ profile.push('(allow network-bind (local ip "*:*"))');
375
+ profile.push('(allow network-inbound (local ip "*:*"))');
376
+ profile.push('(allow network-outbound (local ip "*:*"))');
377
+ }
378
+ // Unix domain sockets for local IPC (SSH agent, Docker, Gradle, etc.)
379
+ // Three separate operations must be allowed:
380
+ // 1. system-socket: socket(AF_UNIX, ...) syscall — creates the socket fd (no path context)
381
+ // 2. network-bind: bind() to a local Unix socket path
382
+ // 3. network-outbound: connect() to a remote Unix socket path
383
+ // Note: (subpath ...) and (path-regex ...) are path-based filters that can only match
384
+ // bind/connect operations — socket() creation has no path, so it requires system-socket.
385
+ if (allowAllUnixSockets) {
386
+ // Allow creating AF_UNIX sockets and all Unix socket paths
387
+ profile.push('(allow system-socket (socket-domain AF_UNIX))');
388
+ profile.push('(allow network-bind (local unix-socket (path-regex #"^/")))');
389
+ profile.push('(allow network-outbound (remote unix-socket (path-regex #"^/")))');
390
+ }
391
+ else if (allowUnixSockets && allowUnixSockets.length > 0) {
392
+ // Allow creating AF_UNIX sockets (required for any Unix socket use)
393
+ profile.push('(allow system-socket (socket-domain AF_UNIX))');
394
+ // Allow specific Unix socket paths
395
+ for (const socketPath of allowUnixSockets) {
396
+ const normalizedPath = normalizePathForSandbox(socketPath);
397
+ profile.push(`(allow network-bind (local unix-socket (subpath ${escapePath(normalizedPath)})))`);
398
+ profile.push(`(allow network-outbound (remote unix-socket (subpath ${escapePath(normalizedPath)})))`);
399
+ }
400
+ }
401
+ // If both allowAllUnixSockets and allowUnixSockets are false/undefined/empty, Unix sockets are blocked by default
402
+ // Allow localhost TCP operations for the HTTP proxy
403
+ if (httpProxyPort !== undefined) {
404
+ profile.push(`(allow network-bind (local ip "localhost:${httpProxyPort}"))`);
405
+ profile.push(`(allow network-inbound (local ip "localhost:${httpProxyPort}"))`);
406
+ profile.push(`(allow network-outbound (remote ip "localhost:${httpProxyPort}"))`);
407
+ }
408
+ // Allow localhost TCP operations for the SOCKS proxy
409
+ if (socksProxyPort !== undefined) {
410
+ profile.push(`(allow network-bind (local ip "localhost:${socksProxyPort}"))`);
411
+ profile.push(`(allow network-inbound (local ip "localhost:${socksProxyPort}"))`);
412
+ profile.push(`(allow network-outbound (remote ip "localhost:${socksProxyPort}"))`);
413
+ }
414
+ }
415
+ profile.push('');
416
+ // Read rules
417
+ profile.push('; File read');
418
+ profile.push(...generateReadRules(readConfig, logTag));
419
+ profile.push('');
420
+ // Write rules
421
+ profile.push('; File write');
422
+ profile.push(...generateWriteRules(writeConfig, logTag, allowGitConfig));
423
+ // Pseudo-terminal (pty) support
424
+ if (allowPty) {
425
+ profile.push('');
426
+ profile.push('; Pseudo-terminal (pty) support');
427
+ profile.push('(allow pseudo-tty)');
428
+ profile.push('(allow file-ioctl');
429
+ profile.push(' (literal "/dev/ptmx")');
430
+ profile.push(' (regex #"^/dev/ttys")');
431
+ profile.push(')');
432
+ profile.push('(allow file-read* file-write*');
433
+ profile.push(' (literal "/dev/ptmx")');
434
+ profile.push(' (regex #"^/dev/ttys")');
435
+ profile.push(')');
436
+ }
437
+ return profile.join('\n');
438
+ }
439
+ /**
440
+ * Escape path for sandbox profile using JSON.stringify for proper escaping
441
+ */
442
+ function escapePath(pathStr) {
443
+ return JSON.stringify(pathStr);
444
+ }
445
+ /**
446
+ * Get TMPDIR parent directory if it matches macOS pattern /var/folders/XX/YYY/T/
447
+ * Returns both /var/ and /private/var/ versions since /var is a symlink
448
+ */
449
+ function getTmpdirParentIfMacOSPattern() {
450
+ const tmpdir = process.env.TMPDIR;
451
+ if (!tmpdir)
452
+ return [];
453
+ const match = tmpdir.match(/^\/(private\/)?var\/folders\/[^/]{2}\/[^/]+\/T\/?$/);
454
+ if (!match)
455
+ return [];
456
+ const parent = tmpdir.replace(/\/T\/?$/, '');
457
+ // Return both /var/ and /private/var/ versions since /var is a symlink
458
+ if (parent.startsWith('/private/var/')) {
459
+ return [parent, parent.replace('/private', '')];
460
+ }
461
+ else if (parent.startsWith('/var/')) {
462
+ return [parent, '/private' + parent];
463
+ }
464
+ return [parent];
465
+ }
466
+ /**
467
+ * Wrap command with macOS sandbox
468
+ */
469
+ export function wrapCommandWithSandboxMacOS(params) {
470
+ const { command, needsNetworkRestriction, httpProxyPort, socksProxyPort, allowUnixSockets, allowAllUnixSockets, allowLocalBinding, readConfig, writeConfig, allowPty, allowGitConfig = false, enableWeakerNetworkIsolation = false, binShell, } = params;
471
+ // Determine if we have restrictions to apply
472
+ // Read: denyOnly pattern - empty array means no restrictions
473
+ // Write: allowOnly pattern - undefined means no restrictions, any config means restrictions
474
+ const hasReadRestrictions = readConfig && readConfig.denyOnly.length > 0;
475
+ const hasWriteRestrictions = writeConfig !== undefined;
476
+ // No sandboxing needed
477
+ if (!needsNetworkRestriction &&
478
+ !hasReadRestrictions &&
479
+ !hasWriteRestrictions) {
480
+ return command;
481
+ }
482
+ const logTag = generateLogTag(command);
483
+ const profile = generateSandboxProfile({
484
+ readConfig,
485
+ writeConfig,
486
+ httpProxyPort,
487
+ socksProxyPort,
488
+ needsNetworkRestriction,
489
+ allowUnixSockets,
490
+ allowAllUnixSockets,
491
+ allowLocalBinding,
492
+ allowPty,
493
+ allowGitConfig,
494
+ enableWeakerNetworkIsolation,
495
+ logTag,
496
+ });
497
+ // Generate proxy environment variables using shared utility
498
+ const proxyEnvArgs = generateProxyEnvVars(httpProxyPort, socksProxyPort);
499
+ // Use the user's shell (zsh, bash, etc.) to ensure aliases/snapshots work
500
+ // Resolve the full path to the shell binary
501
+ const shellName = binShell || 'bash';
502
+ const shell = whichSync(shellName);
503
+ if (!shell) {
504
+ throw new Error(`Shell '${shellName}' not found in PATH`);
505
+ }
506
+ // Use `env` command to set environment variables - each VAR=value is a separate
507
+ // argument that shellquote handles properly, avoiding shell quoting issues
508
+ const wrappedCommand = shellquote.quote([
509
+ 'env',
510
+ ...proxyEnvArgs,
511
+ 'sandbox-exec',
512
+ '-p',
513
+ profile,
514
+ shell,
515
+ '-c',
516
+ command,
517
+ ]);
518
+ logForDebugging(`[Sandbox macOS] Applied restrictions - network: ${!!(httpProxyPort || socksProxyPort)}, read: ${readConfig
519
+ ? 'allowAllExcept' in readConfig
520
+ ? 'allowAllExcept'
521
+ : 'denyAllExcept'
522
+ : 'none'}, write: ${writeConfig
523
+ ? 'allowAllExcept' in writeConfig
524
+ ? 'allowAllExcept'
525
+ : 'denyAllExcept'
526
+ : 'none'}`);
527
+ return wrappedCommand;
528
+ }
529
+ /**
530
+ * Start monitoring macOS system logs for sandbox violations
531
+ * Look for sandbox-related kernel deny events ending in {logTag}
532
+ */
533
+ export function startMacOSSandboxLogMonitor(callback, ignoreViolations) {
534
+ // Pre-compile regex patterns for better performance
535
+ const cmdExtractRegex = /CMD64_(.+?)_END/;
536
+ const sandboxExtractRegex = /Sandbox:\s+(.+)$/;
537
+ // Pre-process ignore patterns for faster lookup
538
+ const wildcardPaths = ignoreViolations?.['*'] || [];
539
+ const commandPatterns = ignoreViolations
540
+ ? Object.entries(ignoreViolations).filter(([pattern]) => pattern !== '*')
541
+ : [];
542
+ // Stream and filter kernel logs for all sandbox violations
543
+ // We can't filter by specific logTag since it's dynamic per command
544
+ const logProcess = spawn('log', [
545
+ 'stream',
546
+ '--predicate',
547
+ `(eventMessage ENDSWITH "${sessionSuffix}")`,
548
+ '--style',
549
+ 'compact',
550
+ ]);
551
+ logProcess.stdout?.on('data', (data) => {
552
+ const lines = data.toString().split('\n');
553
+ // Get violation and command lines
554
+ const violationLine = lines.find(line => line.includes('Sandbox:') && line.includes('deny'));
555
+ const commandLine = lines.find(line => line.startsWith('CMD64_'));
556
+ if (!violationLine)
557
+ return;
558
+ // Extract violation details
559
+ const sandboxMatch = violationLine.match(sandboxExtractRegex);
560
+ if (!sandboxMatch?.[1])
561
+ return;
562
+ const violationDetails = sandboxMatch[1];
563
+ // Try to get command
564
+ let command;
565
+ let encodedCommand;
566
+ if (commandLine) {
567
+ const cmdMatch = commandLine.match(cmdExtractRegex);
568
+ encodedCommand = cmdMatch?.[1];
569
+ if (encodedCommand) {
570
+ try {
571
+ command = decodeSandboxedCommand(encodedCommand);
572
+ }
573
+ catch {
574
+ // Failed to decode, continue without command
575
+ }
576
+ }
577
+ }
578
+ // Always filter out noisey violations
579
+ if (violationDetails.includes('mDNSResponder') ||
580
+ violationDetails.includes('mach-lookup com.apple.diagnosticd') ||
581
+ violationDetails.includes('mach-lookup com.apple.analyticsd')) {
582
+ return;
583
+ }
584
+ // Check if we should ignore this violation
585
+ if (ignoreViolations && command) {
586
+ // Check wildcard patterns first
587
+ if (wildcardPaths.length > 0) {
588
+ const shouldIgnore = wildcardPaths.some(path => violationDetails.includes(path));
589
+ if (shouldIgnore)
590
+ return;
591
+ }
592
+ // Check command-specific patterns
593
+ for (const [pattern, paths] of commandPatterns) {
594
+ if (command.includes(pattern)) {
595
+ const shouldIgnore = paths.some(path => violationDetails.includes(path));
596
+ if (shouldIgnore)
597
+ return;
598
+ }
599
+ }
600
+ }
601
+ // Not ignored - report the violation
602
+ callback({
603
+ line: violationDetails,
604
+ command,
605
+ encodedCommand,
606
+ timestamp: new Date(), // We could parse the timestamp from the log but this feels more reliable
607
+ });
608
+ });
609
+ logProcess.stderr?.on('data', (data) => {
610
+ logForDebugging(`[Sandbox Monitor] Log stream stderr: ${data.toString()}`);
611
+ });
612
+ logProcess.on('error', (error) => {
613
+ logForDebugging(`[Sandbox Monitor] Failed to start log stream: ${error.message}`);
614
+ });
615
+ logProcess.on('exit', (code) => {
616
+ logForDebugging(`[Sandbox Monitor] Log stream exited with code: ${code}`);
617
+ });
618
+ return () => {
619
+ logForDebugging('[Sandbox Monitor] Stopping log monitor');
620
+ logProcess.kill('SIGTERM');
621
+ };
622
+ }
623
+ //# sourceMappingURL=macos-sandbox-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"macos-sandbox-utils.js","sourceRoot":"","sources":["../../src/sandbox/macos-sandbox-utils.ts"],"names":[],"mappings":"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"}