@sysid/sandbox-runtime-improved 0.0.43-sysid.6 → 0.0.49-sysid.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.
- package/README.md +24 -34
- package/dist/sandbox/generate-seccomp-filter.d.ts +0 -51
- package/dist/sandbox/generate-seccomp-filter.d.ts.map +1 -1
- package/dist/sandbox/generate-seccomp-filter.js +0 -106
- package/dist/sandbox/generate-seccomp-filter.js.map +1 -1
- package/dist/sandbox/linux-sandbox-utils.d.ts +21 -19
- package/dist/sandbox/linux-sandbox-utils.d.ts.map +1 -1
- package/dist/sandbox/linux-sandbox-utils.js +190 -118
- package/dist/sandbox/linux-sandbox-utils.js.map +1 -1
- package/dist/sandbox/macos-sandbox-utils.d.ts +1 -1
- package/dist/sandbox/macos-sandbox-utils.d.ts.map +1 -1
- package/dist/sandbox/macos-sandbox-utils.js +50 -20
- package/dist/sandbox/macos-sandbox-utils.js.map +1 -1
- package/dist/sandbox/sandbox-config.d.ts +16 -12
- package/dist/sandbox/sandbox-config.d.ts.map +1 -1
- package/dist/sandbox/sandbox-config.js +17 -10
- package/dist/sandbox/sandbox-config.js.map +1 -1
- package/dist/sandbox/sandbox-manager.d.ts +1 -1
- package/dist/sandbox/sandbox-manager.d.ts.map +1 -1
- package/dist/sandbox/sandbox-manager.js +9 -11
- package/dist/sandbox/sandbox-manager.js.map +1 -1
- package/dist/vendor/seccomp/build.ts +91 -0
- package/dist/vendor/seccomp-src/apply-seccomp.c +232 -50
- package/dist/vendor/seccomp-src/seccomp-unix-block.c +50 -3
- package/package.json +3 -8
- package/vendor/seccomp/build.ts +91 -0
- package/vendor/seccomp-src/apply-seccomp.c +232 -50
- package/vendor/seccomp-src/seccomp-unix-block.c +50 -3
- package/dist/vendor/seccomp/arm64/apply-seccomp +0 -0
- package/dist/vendor/seccomp/arm64/unix-block.bpf +0 -0
- package/dist/vendor/seccomp/x64/apply-seccomp +0 -0
- package/dist/vendor/seccomp/x64/unix-block.bpf +0 -0
- package/vendor/seccomp/arm64/apply-seccomp +0 -0
- package/vendor/seccomp/arm64/unix-block.bpf +0 -0
- package/vendor/seccomp/x64/apply-seccomp +0 -0
- package/vendor/seccomp/x64/unix-block.bpf +0 -0
package/README.md
CHANGED
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
Based on [Anthropic Sandbox Runtime](https://github.com/anthropic-experimental/sandbox-runtime).
|
|
7
|
-
Why: I just need faster feature cycle-times.
|
|
8
7
|
|
|
9
|
-
This fork will be rebased on [SRT](https://github.com/anthropic-experimental/sandbox-runtime) continuously.
|
|
8
|
+
This fork will be rebased on [SRT](https://github.com/anthropic-experimental/sandbox-runtime) continuously (currently based on upstream **v0.0.49**).
|
|
10
9
|
As new features become available, equivalent local ones will be removed.
|
|
11
10
|
|
|
12
11
|
> Objective: keep as close to original as possible, while allowing selected additional features.
|
|
@@ -17,12 +16,10 @@ As new features become available, equivalent local ones will be removed.
|
|
|
17
16
|
|
|
18
17
|
```json
|
|
19
18
|
{
|
|
20
|
-
"allowBrowserProcess": false
|
|
21
|
-
"allowMachLookup": ["com.1password.*"]
|
|
19
|
+
"allowBrowserProcess": false
|
|
22
20
|
}
|
|
23
21
|
```
|
|
24
|
-
- `allowBrowserProcess` -
|
|
25
|
-
- `allowMachLookup` - Additional Mach/XPC service names to allow in the macOS sandbox (string array, optional). Names ending with `*` use prefix matching (e.g., `"com.1password.*"`). Use for tools like 1Password CLI that need specific services. *(fork-only, mirrors [upstream PR #92](https://github.com/anthropic-experimental/sandbox-runtime/pull/92))*
|
|
22
|
+
- `allowBrowserProcess` - **Significantly weakens the macOS sandbox.** Grants `(allow mach*)`, `(allow process-info*)`, `(allow iokit-open)`, and `(allow ipc-posix-shm*)` — permissions Chromium-based browsers need to launch. Filesystem and network restrictions remain enforced. Only enable for browser automation (e.g. `agent-browser`). (boolean, default: false) *(fork-only)*
|
|
26
23
|
|
|
27
24
|
---
|
|
28
25
|
|
|
@@ -324,10 +321,10 @@ Uses an **allow-only pattern** - all network access is denied by default.
|
|
|
324
321
|
|
|
325
322
|
**Unix Socket Settings** (platform-specific behavior):
|
|
326
323
|
|
|
327
|
-
| Setting
|
|
328
|
-
|
|
329
|
-
| `allowUnixSockets: string[]`
|
|
330
|
-
| `allowAllUnixSockets: boolean` | Allow all sockets
|
|
324
|
+
| Setting | macOS | Linux |
|
|
325
|
+
| ------------------------------ | ------------------------- | ---------------------------------------- |
|
|
326
|
+
| `allowUnixSockets: string[]` | Allowlist of socket paths | _Ignored_ (seccomp can't filter by path) |
|
|
327
|
+
| `allowAllUnixSockets: boolean` | Allow all sockets | Disable seccomp blocking |
|
|
331
328
|
|
|
332
329
|
Unix sockets are **blocked by default** on both platforms.
|
|
333
330
|
|
|
@@ -383,7 +380,6 @@ Examples:
|
|
|
383
380
|
- `ignoreViolations` - Object mapping command patterns to arrays of paths where violations should be ignored
|
|
384
381
|
- `enableWeakerNestedSandbox` - Enable weaker sandbox mode for Docker environments (boolean, default: false)
|
|
385
382
|
- `enableWeakerNetworkIsolation` - Allow access to `com.apple.trustd.agent` in the macOS sandbox (boolean, default: false). This is needed for Go programs (`gh`, `gcloud`, `terraform`, `kubectl`, etc.) to verify TLS certificates when using `httpProxyPort` with a MITM proxy and custom CA. **Security warning:** enabling this opens a potential data exfiltration vector through the trustd service.
|
|
386
|
-
- `allowMachLookup` - Additional Mach/XPC service names to allow in the macOS sandbox (string array, optional). Names ending with `*` use prefix matching (e.g., `"com.1password.*"` allows all 1Password services). Others use exact matching.
|
|
387
383
|
|
|
388
384
|
### Common Configuration Recipes
|
|
389
385
|
|
|
@@ -476,6 +472,14 @@ Watchman accesses files outside the sandbox boundaries, which will trigger permi
|
|
|
476
472
|
- Fedora: `dnf install ripgrep`
|
|
477
473
|
- Arch: `pacman -S ripgrep`
|
|
478
474
|
|
|
475
|
+
**Ubuntu 24.04+ note:** These releases enable `kernel.apparmor_restrict_unprivileged_userns` by default, which allows `unshare(CLONE_NEWUSER)` but strips capabilities from the resulting namespace. Both bubblewrap and the seccomp isolation layer need capability-bearing user namespaces. Disable the restriction with:
|
|
476
|
+
|
|
477
|
+
```bash
|
|
478
|
+
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
or add an AppArmor profile that grants `userns` to the relevant binaries.
|
|
482
|
+
|
|
479
483
|
**Optional Linux dependencies (for seccomp fallback):**
|
|
480
484
|
|
|
481
485
|
The package includes pre-generated seccomp BPF filters for x86-64 and arm architectures. These dependencies are only needed if you are on a different architecture where pre-generated filters are not available:
|
|
@@ -501,15 +505,9 @@ npm install
|
|
|
501
505
|
# Build the project
|
|
502
506
|
npm run build
|
|
503
507
|
|
|
504
|
-
# Build seccomp binaries (requires Docker)
|
|
505
|
-
npm run build:seccomp
|
|
506
|
-
|
|
507
508
|
# Run tests
|
|
508
509
|
npm test
|
|
509
510
|
|
|
510
|
-
# Run integration tests
|
|
511
|
-
npm run test:integration
|
|
512
|
-
|
|
513
511
|
# Type checking
|
|
514
512
|
npm run typecheck
|
|
515
513
|
|
|
@@ -522,18 +520,7 @@ npm run format
|
|
|
522
520
|
|
|
523
521
|
### Building Seccomp Binaries
|
|
524
522
|
|
|
525
|
-
The
|
|
526
|
-
|
|
527
|
-
```bash
|
|
528
|
-
npm run build:seccomp
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
This script uses Docker to cross-compile seccomp binaries for multiple architectures:
|
|
532
|
-
|
|
533
|
-
- x64 (x86-64)
|
|
534
|
-
- arm64 (aarch64)
|
|
535
|
-
|
|
536
|
-
The script builds static generator binaries, generates the BPF filters (~104 bytes each), and stores them in `vendor/seccomp/x64/` and `vendor/seccomp/arm64/`. The generator binaries are removed to keep the package size small.
|
|
523
|
+
The BPF filter and `apply-seccomp` loader are compiled from C source in `vendor/seccomp-src/` via `npm run build:seccomp` (Linux only; needs `gcc` and `libseccomp-dev`). CI runs it before tests on each Linux arch, and the release workflow builds both arches and bundles them into the published package.
|
|
537
524
|
|
|
538
525
|
## Implementation Details
|
|
539
526
|
|
|
@@ -625,20 +612,23 @@ On Linux, the sandbox uses **seccomp BPF (Berkeley Packet Filter)** to block Uni
|
|
|
625
612
|
|
|
626
613
|
**How it works:**
|
|
627
614
|
|
|
628
|
-
1. **
|
|
615
|
+
1. **Baked-in BPF filter**: The package ships a static `apply-seccomp` binary for x64 and arm64 with the seccomp BPF filter compiled in. The filter is architecture-specific but libc-independent, so the binary works with both glibc and musl.
|
|
629
616
|
|
|
630
|
-
2. **Runtime detection**: The sandbox automatically detects your system's architecture and
|
|
617
|
+
2. **Runtime detection**: The sandbox automatically detects your system's architecture and uses the matching `apply-seccomp` binary.
|
|
631
618
|
|
|
632
619
|
3. **Syscall filtering**: The BPF filter intercepts the `socket()` syscall and blocks creation of `AF_UNIX` sockets by returning `EPERM`. This prevents sandboxed code from creating new Unix domain sockets.
|
|
633
620
|
|
|
634
621
|
4. **Two-stage application using apply-seccomp binary**:
|
|
635
622
|
- Outer bwrap creates the sandbox with filesystem, network, and PID namespace restrictions
|
|
636
623
|
- Network bridging processes (socat) start inside the sandbox (need Unix sockets)
|
|
637
|
-
- apply-seccomp
|
|
638
|
-
- apply-seccomp
|
|
624
|
+
- apply-seccomp creates a nested user+PID+mount namespace and remounts `/proc`
|
|
625
|
+
- Inside the nested namespace, apply-seccomp acts as PID 1 (non-dumpable init/reaper)
|
|
626
|
+
- apply-seccomp forks, applies the seccomp filter via `prctl()`, and execs the user command
|
|
639
627
|
- User command runs with all sandbox restrictions plus Unix socket creation blocking
|
|
640
628
|
|
|
641
|
-
**
|
|
629
|
+
**PID namespace isolation**: The nested PID namespace ensures the user command cannot see or address any process that runs without the seccomp filter (bwrap's init, the shell wrapper, or the socat helpers). This keeps the seccomp boundary intact regardless of `kernel.yama.ptrace_scope`, since unfiltered helpers are not reachable via `ptrace` or `/proc/N/mem`. The inner PID 1 sets `PR_SET_DUMPABLE=0` so it is not ptraceable either. If nested namespace creation fails, apply-seccomp aborts rather than running without isolation.
|
|
630
|
+
|
|
631
|
+
**Security limitations**: The filter blocks `socket(AF_UNIX, ...)` and the `io_uring_setup`/`io_uring_enter`/`io_uring_register` syscalls (the latter three because `IORING_OP_SOCKET` on Linux 5.19+ would otherwise bypass the `socket()` rule). It does not prevent operations on Unix socket file descriptors inherited from parent processes or passed via `SCM_RIGHTS`. For most sandboxing scenarios, blocking socket creation is sufficient to prevent unauthorized IPC.
|
|
642
632
|
|
|
643
633
|
**Zero runtime dependencies**: Pre-built static apply-seccomp binaries and pre-generated BPF filters are included for x64 and arm64 architectures. No compilation tools or external dependencies required at runtime.
|
|
644
634
|
|
|
@@ -1,22 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Get the path to a pre-generated BPF filter file from the vendor directory
|
|
3
|
-
* Returns the path if it exists, null otherwise
|
|
4
|
-
*
|
|
5
|
-
* Pre-generated BPF files are organized by architecture:
|
|
6
|
-
* - vendor/seccomp/{x64,arm64}/unix-block.bpf
|
|
7
|
-
*
|
|
8
|
-
* Tries multiple paths for resilience:
|
|
9
|
-
* 0. Explicit path provided via parameter (checked first if provided)
|
|
10
|
-
* 1. vendor/seccomp/{arch}/unix-block.bpf (bundled - when bundled into consuming packages)
|
|
11
|
-
* 2. ../../vendor/seccomp/{arch}/unix-block.bpf (package root - standard npm installs)
|
|
12
|
-
* 3. ../vendor/seccomp/{arch}/unix-block.bpf (dist/vendor - for bundlers)
|
|
13
|
-
* 4. Global npm install (if seccompBinaryPath not provided) - for native builds
|
|
14
|
-
*
|
|
15
|
-
* @param seccompBinaryPath - Optional explicit path to the BPF filter file. If provided and
|
|
16
|
-
* exists, it will be used. If not provided, falls back to searching local paths and then
|
|
17
|
-
* global npm install (for native builds where vendor directory isn't bundled).
|
|
18
|
-
*/
|
|
19
|
-
export declare function getPreGeneratedBpfPath(seccompBinaryPath?: string): string | null;
|
|
20
1
|
/**
|
|
21
2
|
* Get the path to the apply-seccomp binary from the vendor directory
|
|
22
3
|
* Returns the path if it exists, null otherwise
|
|
@@ -36,36 +17,4 @@ export declare function getPreGeneratedBpfPath(seccompBinaryPath?: string): stri
|
|
|
36
17
|
* then global npm install (for native builds where vendor directory isn't bundled).
|
|
37
18
|
*/
|
|
38
19
|
export declare function getApplySeccompBinaryPath(seccompBinaryPath?: string): string | null;
|
|
39
|
-
/**
|
|
40
|
-
* Get the path to a pre-generated seccomp BPF filter that blocks Unix domain socket creation
|
|
41
|
-
* Returns the path to the BPF filter file, or null if not available
|
|
42
|
-
*
|
|
43
|
-
* The filter blocks socket(AF_UNIX, ...) syscalls while allowing all other syscalls.
|
|
44
|
-
* This prevents creation of new Unix domain socket file descriptors.
|
|
45
|
-
*
|
|
46
|
-
* Security scope:
|
|
47
|
-
* - Blocks: socket(AF_UNIX, ...) syscall (creating new Unix socket FDs)
|
|
48
|
-
* - Does NOT block: Operations on inherited Unix socket FDs (bind, connect, sendto, etc.)
|
|
49
|
-
* - Does NOT block: Unix socket FDs passed via SCM_RIGHTS
|
|
50
|
-
* - For most sandboxing scenarios, blocking socket creation is sufficient
|
|
51
|
-
*
|
|
52
|
-
* Note: This blocks ALL Unix socket creation, regardless of path. The allowUnixSockets
|
|
53
|
-
* configuration is not supported on Linux due to seccomp-bpf limitations (it cannot
|
|
54
|
-
* read user-space memory to inspect socket paths).
|
|
55
|
-
*
|
|
56
|
-
* Requirements:
|
|
57
|
-
* - Pre-generated BPF filters included for x64 and ARM64 only
|
|
58
|
-
* - Other architectures are not supported
|
|
59
|
-
*
|
|
60
|
-
* @param seccompBinaryPath - Optional explicit path to the BPF filter file
|
|
61
|
-
* @returns Path to the pre-generated BPF filter file, or null if not available
|
|
62
|
-
*/
|
|
63
|
-
export declare function generateSeccompFilter(seccompBinaryPath?: string): string | null;
|
|
64
|
-
/**
|
|
65
|
-
* Clean up a seccomp filter file
|
|
66
|
-
* Since we only use pre-generated BPF files from vendor/, this is a no-op.
|
|
67
|
-
* Pre-generated files are never deleted.
|
|
68
|
-
* Kept for backward compatibility with existing code that calls it.
|
|
69
|
-
*/
|
|
70
|
-
export declare function cleanupSeccompFilter(_filterPath: string): void;
|
|
71
20
|
//# sourceMappingURL=generate-seccomp-filter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-seccomp-filter.d.ts","sourceRoot":"","sources":["../../src/sandbox/generate-seccomp-filter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate-seccomp-filter.d.ts","sourceRoot":"","sources":["../../src/sandbox/generate-seccomp-filter.ts"],"names":[],"mappings":"AA6IA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,iBAAiB,CAAC,EAAE,MAAM,GACzB,MAAM,GAAG,IAAI,CASf"}
|
|
@@ -5,7 +5,6 @@ import { execSync } from 'node:child_process';
|
|
|
5
5
|
import { homedir } from 'node:os';
|
|
6
6
|
import { logForDebugging } from '../utils/debug.js';
|
|
7
7
|
// Cache for path lookups (key: explicit path or empty string, value: resolved path or null)
|
|
8
|
-
const bpfPathCache = new Map();
|
|
9
8
|
const applySeccompPathCache = new Map();
|
|
10
9
|
// Cache for global npm paths (computed once per process)
|
|
11
10
|
let cachedGlobalNpmPaths = null;
|
|
@@ -95,68 +94,6 @@ function getLocalSeccompPaths(filename) {
|
|
|
95
94
|
join(baseDir, '..', relativePath), // dist: dist/vendor/seccomp/...
|
|
96
95
|
];
|
|
97
96
|
}
|
|
98
|
-
/**
|
|
99
|
-
* Get the path to a pre-generated BPF filter file from the vendor directory
|
|
100
|
-
* Returns the path if it exists, null otherwise
|
|
101
|
-
*
|
|
102
|
-
* Pre-generated BPF files are organized by architecture:
|
|
103
|
-
* - vendor/seccomp/{x64,arm64}/unix-block.bpf
|
|
104
|
-
*
|
|
105
|
-
* Tries multiple paths for resilience:
|
|
106
|
-
* 0. Explicit path provided via parameter (checked first if provided)
|
|
107
|
-
* 1. vendor/seccomp/{arch}/unix-block.bpf (bundled - when bundled into consuming packages)
|
|
108
|
-
* 2. ../../vendor/seccomp/{arch}/unix-block.bpf (package root - standard npm installs)
|
|
109
|
-
* 3. ../vendor/seccomp/{arch}/unix-block.bpf (dist/vendor - for bundlers)
|
|
110
|
-
* 4. Global npm install (if seccompBinaryPath not provided) - for native builds
|
|
111
|
-
*
|
|
112
|
-
* @param seccompBinaryPath - Optional explicit path to the BPF filter file. If provided and
|
|
113
|
-
* exists, it will be used. If not provided, falls back to searching local paths and then
|
|
114
|
-
* global npm install (for native builds where vendor directory isn't bundled).
|
|
115
|
-
*/
|
|
116
|
-
export function getPreGeneratedBpfPath(seccompBinaryPath) {
|
|
117
|
-
const cacheKey = seccompBinaryPath ?? '';
|
|
118
|
-
if (bpfPathCache.has(cacheKey)) {
|
|
119
|
-
return bpfPathCache.get(cacheKey);
|
|
120
|
-
}
|
|
121
|
-
const result = findBpfPath(seccompBinaryPath);
|
|
122
|
-
bpfPathCache.set(cacheKey, result);
|
|
123
|
-
return result;
|
|
124
|
-
}
|
|
125
|
-
// NOTE: This is a slow operation (synchronous fs lookups + execSync). Ensure calls
|
|
126
|
-
// are memoized at the top level rather than invoked repeatedly.
|
|
127
|
-
function findBpfPath(seccompBinaryPath) {
|
|
128
|
-
// Check explicit path first (highest priority)
|
|
129
|
-
if (seccompBinaryPath) {
|
|
130
|
-
if (fs.existsSync(seccompBinaryPath)) {
|
|
131
|
-
logForDebugging(`[SeccompFilter] Using BPF filter from explicit path: ${seccompBinaryPath}`);
|
|
132
|
-
return seccompBinaryPath;
|
|
133
|
-
}
|
|
134
|
-
logForDebugging(`[SeccompFilter] Explicit path provided but file not found: ${seccompBinaryPath}`);
|
|
135
|
-
}
|
|
136
|
-
const arch = getVendorArchitecture();
|
|
137
|
-
if (!arch) {
|
|
138
|
-
logForDebugging(`[SeccompFilter] Cannot find pre-generated BPF filter: unsupported architecture ${process.arch}`);
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
logForDebugging(`[SeccompFilter] Detected architecture: ${arch}`);
|
|
142
|
-
// Check local paths first (bundled or package install)
|
|
143
|
-
for (const bpfPath of getLocalSeccompPaths('unix-block.bpf')) {
|
|
144
|
-
if (fs.existsSync(bpfPath)) {
|
|
145
|
-
logForDebugging(`[SeccompFilter] Found pre-generated BPF filter: ${bpfPath} (${arch})`);
|
|
146
|
-
return bpfPath;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
// Fallback: check global npm install (for native builds without bundled vendor)
|
|
150
|
-
for (const globalBase of getGlobalNpmPaths()) {
|
|
151
|
-
const bpfPath = join(globalBase, 'vendor', 'seccomp', arch, 'unix-block.bpf');
|
|
152
|
-
if (fs.existsSync(bpfPath)) {
|
|
153
|
-
logForDebugging(`[SeccompFilter] Found pre-generated BPF filter in global install: ${bpfPath} (${arch})`);
|
|
154
|
-
return bpfPath;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
logForDebugging(`[SeccompFilter] Pre-generated BPF filter not found in any expected location (${arch})`);
|
|
158
|
-
return null;
|
|
159
|
-
}
|
|
160
97
|
/**
|
|
161
98
|
* Get the path to the apply-seccomp binary from the vendor directory
|
|
162
99
|
* Returns the path if it exists, null otherwise
|
|
@@ -217,47 +154,4 @@ function findApplySeccompPath(seccompBinaryPath) {
|
|
|
217
154
|
logForDebugging(`[SeccompFilter] apply-seccomp binary not found in any expected location (${arch})`);
|
|
218
155
|
return null;
|
|
219
156
|
}
|
|
220
|
-
/**
|
|
221
|
-
* Get the path to a pre-generated seccomp BPF filter that blocks Unix domain socket creation
|
|
222
|
-
* Returns the path to the BPF filter file, or null if not available
|
|
223
|
-
*
|
|
224
|
-
* The filter blocks socket(AF_UNIX, ...) syscalls while allowing all other syscalls.
|
|
225
|
-
* This prevents creation of new Unix domain socket file descriptors.
|
|
226
|
-
*
|
|
227
|
-
* Security scope:
|
|
228
|
-
* - Blocks: socket(AF_UNIX, ...) syscall (creating new Unix socket FDs)
|
|
229
|
-
* - Does NOT block: Operations on inherited Unix socket FDs (bind, connect, sendto, etc.)
|
|
230
|
-
* - Does NOT block: Unix socket FDs passed via SCM_RIGHTS
|
|
231
|
-
* - For most sandboxing scenarios, blocking socket creation is sufficient
|
|
232
|
-
*
|
|
233
|
-
* Note: This blocks ALL Unix socket creation, regardless of path. The allowUnixSockets
|
|
234
|
-
* configuration is not supported on Linux due to seccomp-bpf limitations (it cannot
|
|
235
|
-
* read user-space memory to inspect socket paths).
|
|
236
|
-
*
|
|
237
|
-
* Requirements:
|
|
238
|
-
* - Pre-generated BPF filters included for x64 and ARM64 only
|
|
239
|
-
* - Other architectures are not supported
|
|
240
|
-
*
|
|
241
|
-
* @param seccompBinaryPath - Optional explicit path to the BPF filter file
|
|
242
|
-
* @returns Path to the pre-generated BPF filter file, or null if not available
|
|
243
|
-
*/
|
|
244
|
-
export function generateSeccompFilter(seccompBinaryPath) {
|
|
245
|
-
const preGeneratedBpf = getPreGeneratedBpfPath(seccompBinaryPath);
|
|
246
|
-
if (preGeneratedBpf) {
|
|
247
|
-
logForDebugging('[SeccompFilter] Using pre-generated BPF filter');
|
|
248
|
-
return preGeneratedBpf;
|
|
249
|
-
}
|
|
250
|
-
logForDebugging('[SeccompFilter] Pre-generated BPF filter not available for this architecture. ' +
|
|
251
|
-
'Only x64 and arm64 are supported.', { level: 'error' });
|
|
252
|
-
return null;
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* Clean up a seccomp filter file
|
|
256
|
-
* Since we only use pre-generated BPF files from vendor/, this is a no-op.
|
|
257
|
-
* Pre-generated files are never deleted.
|
|
258
|
-
* Kept for backward compatibility with existing code that calls it.
|
|
259
|
-
*/
|
|
260
|
-
export function cleanupSeccompFilter(_filterPath) {
|
|
261
|
-
// No-op: pre-generated BPF files are never cleaned up
|
|
262
|
-
}
|
|
263
157
|
//# sourceMappingURL=generate-seccomp-filter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-seccomp-filter.js","sourceRoot":"","sources":["../../src/sandbox/generate-seccomp-filter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAEnD,4FAA4F;AAC5F,MAAM,
|
|
1
|
+
{"version":3,"file":"generate-seccomp-filter.js","sourceRoot":"","sources":["../../src/sandbox/generate-seccomp-filter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ChildProcess } from 'node:child_process';
|
|
2
2
|
import type { FsReadRestrictionConfig, FsWriteRestrictionConfig } from './sandbox-schemas.js';
|
|
3
|
+
import type { SeccompConfig } from './sandbox-config.js';
|
|
3
4
|
export interface LinuxNetworkBridgeContext {
|
|
4
5
|
httpSocketPath: string;
|
|
5
6
|
socksSocketPath: string;
|
|
@@ -29,10 +30,7 @@ export interface LinuxSandboxParams {
|
|
|
29
30
|
/** Allow writes to .git/config files (default: false) */
|
|
30
31
|
allowGitConfig?: boolean;
|
|
31
32
|
/** Custom seccomp binary paths */
|
|
32
|
-
seccompConfig?:
|
|
33
|
-
bpfPath?: string;
|
|
34
|
-
applyPath?: string;
|
|
35
|
-
};
|
|
33
|
+
seccompConfig?: SeccompConfig;
|
|
36
34
|
/** Abort signal to cancel the ripgrep scan */
|
|
37
35
|
abortSignal?: AbortSignal;
|
|
38
36
|
}
|
|
@@ -47,17 +45,25 @@ export interface LinuxSandboxParams {
|
|
|
47
45
|
* ghost dotfiles (e.g. .bashrc, .gitconfig) from appearing in the working
|
|
48
46
|
* directory. It is also called automatically on process exit as a safety net.
|
|
49
47
|
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
48
|
+
* Each call decrements the active-sandbox counter that was incremented by
|
|
49
|
+
* wrapCommandWithSandboxLinux(). File deletion is deferred until the counter
|
|
50
|
+
* reaches zero. Deleting a mount point file on the host while another bwrap
|
|
51
|
+
* instance is still running detaches that instance's bind mount (the dentry
|
|
52
|
+
* is unhashed, so path lookup no longer finds the mount) and the deny rule
|
|
53
|
+
* stops applying inside that sandbox.
|
|
54
|
+
*
|
|
55
|
+
* Pass `{ force: true }` to delete unconditionally — used by the process-exit
|
|
56
|
+
* handler and reset() where deferral is not meaningful.
|
|
52
57
|
*/
|
|
53
|
-
export declare function cleanupBwrapMountPoints(
|
|
58
|
+
export declare function cleanupBwrapMountPoints(opts?: {
|
|
59
|
+
force?: boolean;
|
|
60
|
+
}): void;
|
|
54
61
|
/**
|
|
55
62
|
* Detailed status of Linux sandbox dependencies
|
|
56
63
|
*/
|
|
57
64
|
export type LinuxDependencyStatus = {
|
|
58
65
|
hasBwrap: boolean;
|
|
59
66
|
hasSocat: boolean;
|
|
60
|
-
hasSeccompBpf: boolean;
|
|
61
67
|
hasSeccompApply: boolean;
|
|
62
68
|
};
|
|
63
69
|
/**
|
|
@@ -70,17 +76,11 @@ export type SandboxDependencyCheck = {
|
|
|
70
76
|
/**
|
|
71
77
|
* Get detailed status of Linux sandbox dependencies
|
|
72
78
|
*/
|
|
73
|
-
export declare function getLinuxDependencyStatus(seccompConfig?:
|
|
74
|
-
bpfPath?: string;
|
|
75
|
-
applyPath?: string;
|
|
76
|
-
}): LinuxDependencyStatus;
|
|
79
|
+
export declare function getLinuxDependencyStatus(seccompConfig?: SeccompConfig): LinuxDependencyStatus;
|
|
77
80
|
/**
|
|
78
81
|
* Check sandbox dependencies and return structured result
|
|
79
82
|
*/
|
|
80
|
-
export declare function checkLinuxDependencies(seccompConfig?:
|
|
81
|
-
bpfPath?: string;
|
|
82
|
-
applyPath?: string;
|
|
83
|
-
}): SandboxDependencyCheck;
|
|
83
|
+
export declare function checkLinuxDependencies(seccompConfig?: SeccompConfig): SandboxDependencyCheck;
|
|
84
84
|
/**
|
|
85
85
|
* Initialize the Linux network bridge for sandbox networking
|
|
86
86
|
*
|
|
@@ -121,10 +121,12 @@ export declare function initializeLinuxNetworkBridge(httpProxyPort: number, sock
|
|
|
121
121
|
* - Filesystem restrictions are applied (read-only mounts, bind mounts, etc.)
|
|
122
122
|
* - Socat processes start and connect to Unix socket bridges (can use socket(AF_UNIX, ...))
|
|
123
123
|
*
|
|
124
|
-
* Stage 2: apply-seccomp -
|
|
125
|
-
* - apply-seccomp
|
|
126
|
-
* -
|
|
124
|
+
* Stage 2: apply-seccomp - Nested PID namespace + seccomp filter
|
|
125
|
+
* - apply-seccomp creates a nested user+PID+mount namespace and remounts /proc
|
|
126
|
+
* - Inside, apply-seccomp becomes PID 1 (non-dumpable init/reaper)
|
|
127
|
+
* - Forks, sets PR_SET_NO_NEW_PRIVS, applies seccomp via prctl(PR_SET_SECCOMP)
|
|
127
128
|
* - Execs user command with seccomp active (cannot create new Unix sockets)
|
|
129
|
+
* - User command cannot see or ptrace bwrap/bash/socat (separate PID namespace)
|
|
128
130
|
*
|
|
129
131
|
* This solves the conflict between:
|
|
130
132
|
* - Security: Blocking arbitrary Unix socket creation in user commands
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linux-sandbox-utils.d.ts","sourceRoot":"","sources":["../../src/sandbox/linux-sandbox-utils.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAYtD,OAAO,KAAK,EACV,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"linux-sandbox-utils.d.ts","sourceRoot":"","sources":["../../src/sandbox/linux-sandbox-utils.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAYtD,OAAO,KAAK,EACV,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,sBAAsB,CAAA;AAE7B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAExD,MAAM,WAAW,yBAAyB;IACxC,cAAc,EAAE,MAAM,CAAA;IACtB,eAAe,EAAE,MAAM,CAAA;IACvB,iBAAiB,EAAE,YAAY,CAAA;IAC/B,kBAAkB,EAAE,YAAY,CAAA;IAChC,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,uBAAuB,EAAE,OAAO,CAAA;IAChC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,UAAU,CAAC,EAAE,uBAAuB,CAAA;IACpC,WAAW,CAAC,EAAE,wBAAwB,CAAA;IACtC,yBAAyB,CAAC,EAAE,OAAO,CAAA;IACnC,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;IACpD,yEAAyE;IACzE,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,yDAAyD;IACzD,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,kCAAkC;IAClC,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,8CAA8C;IAC9C,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B;AA8PD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAyCxE;AAED;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;IACjB,eAAe,EAAE,OAAO,CAAA;CACzB,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB,CAAA;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,aAAa,CAAC,EAAE,aAAa,GAC5B,qBAAqB,CAUvB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,aAAa,CAAC,EAAE,aAAa,GAC5B,sBAAsB,CAgBxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,yBAAyB,CAAC,CA2HpC;AAsYD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,MAAM,CAAC,CAuOjB"}
|