@voratiq/sandbox-runtime 0.0.29-voratiq0

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