@sysid/sandbox-runtime-improved 0.0.55-sysid.1 → 0.0.61-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.
Files changed (118) hide show
  1. package/README.md +43 -2
  2. package/dist/cli.js +8 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/index.d.ts +6 -6
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -2
  7. package/dist/index.js.map +1 -1
  8. package/dist/sandbox/credential-mask-files.d.ts +72 -0
  9. package/dist/sandbox/credential-mask-files.d.ts.map +1 -0
  10. package/dist/sandbox/credential-mask-files.js +146 -0
  11. package/dist/sandbox/credential-mask-files.js.map +1 -0
  12. package/dist/sandbox/credential-sentinel.d.ts +72 -0
  13. package/dist/sandbox/credential-sentinel.d.ts.map +1 -0
  14. package/dist/sandbox/credential-sentinel.js +130 -0
  15. package/dist/sandbox/credential-sentinel.js.map +1 -0
  16. package/dist/sandbox/domain-pattern.d.ts +36 -0
  17. package/dist/sandbox/domain-pattern.d.ts.map +1 -0
  18. package/dist/sandbox/domain-pattern.js +60 -0
  19. package/dist/sandbox/domain-pattern.js.map +1 -0
  20. package/dist/sandbox/http-proxy.d.ts +32 -1
  21. package/dist/sandbox/http-proxy.d.ts.map +1 -1
  22. package/dist/sandbox/http-proxy.js +10 -2
  23. package/dist/sandbox/http-proxy.js.map +1 -1
  24. package/dist/sandbox/linux-sandbox-utils.d.ts +17 -0
  25. package/dist/sandbox/linux-sandbox-utils.d.ts.map +1 -1
  26. package/dist/sandbox/linux-sandbox-utils.js +155 -47
  27. package/dist/sandbox/linux-sandbox-utils.js.map +1 -1
  28. package/dist/sandbox/listen-in-range.d.ts +12 -0
  29. package/dist/sandbox/listen-in-range.d.ts.map +1 -0
  30. package/dist/sandbox/listen-in-range.js +43 -0
  31. package/dist/sandbox/listen-in-range.js.map +1 -0
  32. package/dist/sandbox/macos-sandbox-utils.d.ts +13 -0
  33. package/dist/sandbox/macos-sandbox-utils.d.ts.map +1 -1
  34. package/dist/sandbox/macos-sandbox-utils.js +76 -14
  35. package/dist/sandbox/macos-sandbox-utils.js.map +1 -1
  36. package/dist/sandbox/mitm-ca.d.ts +18 -2
  37. package/dist/sandbox/mitm-ca.d.ts.map +1 -1
  38. package/dist/sandbox/mitm-ca.js +49 -9
  39. package/dist/sandbox/mitm-ca.js.map +1 -1
  40. package/dist/sandbox/mitm-leaf.d.ts.map +1 -1
  41. package/dist/sandbox/mitm-leaf.js +24 -6
  42. package/dist/sandbox/mitm-leaf.js.map +1 -1
  43. package/dist/sandbox/mux-proxy.d.ts +59 -0
  44. package/dist/sandbox/mux-proxy.d.ts.map +1 -0
  45. package/dist/sandbox/mux-proxy.js +159 -0
  46. package/dist/sandbox/mux-proxy.js.map +1 -0
  47. package/dist/sandbox/request-filter.d.ts +11 -1
  48. package/dist/sandbox/request-filter.d.ts.map +1 -1
  49. package/dist/sandbox/request-filter.js.map +1 -1
  50. package/dist/sandbox/sandbox-config.d.ts +383 -1
  51. package/dist/sandbox/sandbox-config.d.ts.map +1 -1
  52. package/dist/sandbox/sandbox-config.js +252 -1
  53. package/dist/sandbox/sandbox-config.js.map +1 -1
  54. package/dist/sandbox/sandbox-manager.d.ts +4 -0
  55. package/dist/sandbox/sandbox-manager.d.ts.map +1 -1
  56. package/dist/sandbox/sandbox-manager.js +618 -168
  57. package/dist/sandbox/sandbox-manager.js.map +1 -1
  58. package/dist/sandbox/sandbox-schemas.d.ts +27 -0
  59. package/dist/sandbox/sandbox-schemas.d.ts.map +1 -1
  60. package/dist/sandbox/sandbox-utils.d.ts +42 -6
  61. package/dist/sandbox/sandbox-utils.d.ts.map +1 -1
  62. package/dist/sandbox/sandbox-utils.js +115 -27
  63. package/dist/sandbox/sandbox-utils.js.map +1 -1
  64. package/dist/sandbox/socks-proxy.d.ts +11 -5
  65. package/dist/sandbox/socks-proxy.d.ts.map +1 -1
  66. package/dist/sandbox/socks-proxy.js +13 -81
  67. package/dist/sandbox/socks-proxy.js.map +1 -1
  68. package/dist/sandbox/tls-terminate-proxy.d.ts +2 -2
  69. package/dist/sandbox/tls-terminate-proxy.d.ts.map +1 -1
  70. package/dist/sandbox/tls-terminate-proxy.js +31 -5
  71. package/dist/sandbox/tls-terminate-proxy.js.map +1 -1
  72. package/dist/sandbox/windows-sandbox-utils.d.ts +347 -11
  73. package/dist/sandbox/windows-sandbox-utils.d.ts.map +1 -1
  74. package/dist/sandbox/windows-sandbox-utils.js +437 -45
  75. package/dist/sandbox/windows-sandbox-utils.js.map +1 -1
  76. package/package.json +7 -4
  77. package/vendor/seccomp/build.ts +8 -30
  78. package/vendor/srt-win/build.ts +21 -0
  79. package/dist/vendor/seccomp/Dockerfile.build +0 -6
  80. package/dist/vendor/seccomp/arm64/apply-seccomp +0 -0
  81. package/dist/vendor/seccomp/build.ts +0 -91
  82. package/dist/vendor/seccomp/x64/apply-seccomp +0 -0
  83. package/dist/vendor/seccomp-src/apply-seccomp.c +0 -280
  84. package/dist/vendor/seccomp-src/seccomp-unix-block.c +0 -148
  85. package/dist/vendor/srt-win/Cargo.lock +0 -361
  86. package/dist/vendor/srt-win/Cargo.toml +0 -46
  87. package/dist/vendor/srt-win/ci/cleanup.ps1 +0 -49
  88. package/dist/vendor/srt-win/ci/smoke-exec.ps1 +0 -446
  89. package/dist/vendor/srt-win/ci/smoke.ps1 +0 -307
  90. package/dist/vendor/srt-win/src/job.rs +0 -102
  91. package/dist/vendor/srt-win/src/launch.rs +0 -732
  92. package/dist/vendor/srt-win/src/lib.rs +0 -20
  93. package/dist/vendor/srt-win/src/main.rs +0 -669
  94. package/dist/vendor/srt-win/src/self_protect.rs +0 -169
  95. package/dist/vendor/srt-win/src/sid.rs +0 -296
  96. package/dist/vendor/srt-win/src/token.rs +0 -341
  97. package/dist/vendor/srt-win/src/util.rs +0 -42
  98. package/dist/vendor/srt-win/src/wfp.rs +0 -992
  99. package/dist/vendor/srt-win/src/winsta.rs +0 -209
  100. package/dist/vendor/srt-win/tests/sd_access_check_matrix.rs +0 -259
  101. package/vendor/seccomp-src/apply-seccomp.c +0 -280
  102. package/vendor/seccomp-src/seccomp-unix-block.c +0 -148
  103. package/vendor/srt-win/Cargo.lock +0 -361
  104. package/vendor/srt-win/Cargo.toml +0 -46
  105. package/vendor/srt-win/ci/cleanup.ps1 +0 -49
  106. package/vendor/srt-win/ci/smoke-exec.ps1 +0 -446
  107. package/vendor/srt-win/ci/smoke.ps1 +0 -307
  108. package/vendor/srt-win/src/job.rs +0 -102
  109. package/vendor/srt-win/src/launch.rs +0 -732
  110. package/vendor/srt-win/src/lib.rs +0 -20
  111. package/vendor/srt-win/src/main.rs +0 -669
  112. package/vendor/srt-win/src/self_protect.rs +0 -169
  113. package/vendor/srt-win/src/sid.rs +0 -296
  114. package/vendor/srt-win/src/token.rs +0 -341
  115. package/vendor/srt-win/src/util.rs +0 -42
  116. package/vendor/srt-win/src/wfp.rs +0 -992
  117. package/vendor/srt-win/src/winsta.rs +0 -209
  118. package/vendor/srt-win/tests/sd_access_check_matrix.rs +0 -259
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Domain-pattern matching shared between runtime host filtering
3
+ * (sandbox-manager) and config-time validation (sandbox-config).
4
+ * Lives in its own module so the schema can import it without pulling
5
+ * in sandbox-manager (which imports the schema — circular).
6
+ */
7
+ /**
8
+ * Match a hostname against a domain pattern.
9
+ *
10
+ * Patterns:
11
+ * - `*` matches everything (deny-all; the schema only accepts this in
12
+ * deniedDomains).
13
+ * - `*.example.com` matches any strict subdomain of example.com.
14
+ * - anything else matches exactly (case-insensitive).
15
+ *
16
+ * Wildcard suffix matching is refused for IP literals so an IPv6 zone-ID
17
+ * payload like `::ffff:1.2.3.4%x.allowed.com` cannot pass `.endsWith()`
18
+ * while the OS connects to the bare IP. isValidHost already rejects `%`,
19
+ * but we refuse here too for defence in depth.
20
+ */
21
+ export declare function matchesDomainPattern(hostname: string, pattern: string): boolean;
22
+ /**
23
+ * Decide whether a per-credential `injectHosts` entry is reachable via
24
+ * `network.allowedDomains` — i.e. every concrete host that could match
25
+ * `injectHost` is allowed by at least one entry in `allowedDomains`.
26
+ *
27
+ * For an exact `injectHost` (`api.github.com`) this is just
28
+ * `matchesDomainPattern` against each allowed pattern.
29
+ *
30
+ * For a wildcard `injectHost` (`*.X`), an exact allowedDomain can never
31
+ * cover it (it admits only one host), so coverage requires an allowed
32
+ * wildcard `*.Y` whose base is `X` or an ancestor of `X` — e.g.
33
+ * `*.api.github.com` is covered by `*.github.com`.
34
+ */
35
+ export declare function isInjectHostCoveredByAllowedDomains(injectHost: string, allowedDomains: readonly string[]): boolean;
36
+ //# sourceMappingURL=domain-pattern.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain-pattern.d.ts","sourceRoot":"","sources":["../../src/sandbox/domain-pattern.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAST;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mCAAmC,CACjD,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,SAAS,MAAM,EAAE,GAChC,OAAO,CAUT"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Domain-pattern matching shared between runtime host filtering
3
+ * (sandbox-manager) and config-time validation (sandbox-config).
4
+ * Lives in its own module so the schema can import it without pulling
5
+ * in sandbox-manager (which imports the schema — circular).
6
+ */
7
+ import { isIP } from 'node:net';
8
+ import { stripBrackets } from './parent-proxy.js';
9
+ /**
10
+ * Match a hostname against a domain pattern.
11
+ *
12
+ * Patterns:
13
+ * - `*` matches everything (deny-all; the schema only accepts this in
14
+ * deniedDomains).
15
+ * - `*.example.com` matches any strict subdomain of example.com.
16
+ * - anything else matches exactly (case-insensitive).
17
+ *
18
+ * Wildcard suffix matching is refused for IP literals so an IPv6 zone-ID
19
+ * payload like `::ffff:1.2.3.4%x.allowed.com` cannot pass `.endsWith()`
20
+ * while the OS connects to the bare IP. isValidHost already rejects `%`,
21
+ * but we refuse here too for defence in depth.
22
+ */
23
+ export function matchesDomainPattern(hostname, pattern) {
24
+ const h = hostname.toLowerCase();
25
+ if (pattern === '*')
26
+ return true;
27
+ if (pattern.startsWith('*.')) {
28
+ if (isIP(stripBrackets(h)))
29
+ return false;
30
+ const baseDomain = pattern.substring(2).toLowerCase();
31
+ return h.endsWith('.' + baseDomain);
32
+ }
33
+ return h === pattern.toLowerCase();
34
+ }
35
+ /**
36
+ * Decide whether a per-credential `injectHosts` entry is reachable via
37
+ * `network.allowedDomains` — i.e. every concrete host that could match
38
+ * `injectHost` is allowed by at least one entry in `allowedDomains`.
39
+ *
40
+ * For an exact `injectHost` (`api.github.com`) this is just
41
+ * `matchesDomainPattern` against each allowed pattern.
42
+ *
43
+ * For a wildcard `injectHost` (`*.X`), an exact allowedDomain can never
44
+ * cover it (it admits only one host), so coverage requires an allowed
45
+ * wildcard `*.Y` whose base is `X` or an ancestor of `X` — e.g.
46
+ * `*.api.github.com` is covered by `*.github.com`.
47
+ */
48
+ export function isInjectHostCoveredByAllowedDomains(injectHost, allowedDomains) {
49
+ if (!injectHost.startsWith('*.')) {
50
+ return allowedDomains.some(p => matchesDomainPattern(injectHost, p));
51
+ }
52
+ const injectBase = injectHost.slice(2).toLowerCase();
53
+ return allowedDomains.some(p => {
54
+ if (!p.startsWith('*.'))
55
+ return false;
56
+ const allowedBase = p.slice(2).toLowerCase();
57
+ return injectBase === allowedBase || injectBase.endsWith('.' + allowedBase);
58
+ });
59
+ }
60
+ //# sourceMappingURL=domain-pattern.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain-pattern.js","sourceRoot":"","sources":["../../src/sandbox/domain-pattern.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEjD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAAgB,EAChB,OAAe;IAEf,MAAM,CAAC,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAA;IAChC,IAAI,OAAO,KAAK,GAAG;QAAE,OAAO,IAAI,CAAA;IAChC,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAA;QACxC,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;QACrD,OAAO,CAAC,CAAC,QAAQ,CAAC,GAAG,GAAG,UAAU,CAAC,CAAA;IACrC,CAAC;IACD,OAAO,CAAC,KAAK,OAAO,CAAC,WAAW,EAAE,CAAA;AACpC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,mCAAmC,CACjD,UAAkB,EAClB,cAAiC;IAEjC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,oBAAoB,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAA;IACtE,CAAC;IACD,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;IACpD,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;QAC7B,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAA;QACrC,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;QAC5C,OAAO,UAAU,KAAK,WAAW,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,GAAG,WAAW,CAAC,CAAA;IAC7E,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -2,7 +2,7 @@ import type { Socket } from 'node:net';
2
2
  import type { Duplex } from 'node:stream';
3
3
  import type { Server } from 'node:http';
4
4
  import type { MitmCA } from './mitm-ca.js';
5
- import { type FilterRequestCallback } from './request-filter.js';
5
+ import { type FilterRequestCallback, type MutateForwardedHeaders } from './request-filter.js';
6
6
  import type { ResolvedParentProxy } from './parent-proxy.js';
7
7
  export interface HttpProxyServerOptions {
8
8
  filter(port: number, host: string, socket: Socket | Duplex): Promise<boolean> | boolean;
@@ -19,11 +19,42 @@ export interface HttpProxyServerOptions {
19
19
  * config layer (sandbox-manager rejects both being set).
20
20
  */
21
21
  mitmCA?: MitmCA;
22
+ /**
23
+ * Per-host opt-out of TLS termination; consulted only when `mitmCA` is
24
+ * set. Return false to leave that CONNECT as an opaque byte tunnel
25
+ * (still hostname-allowlisted via `filter`, but not content-inspected —
26
+ * the same posture as the non-tlsTerminate path), so the sandboxed
27
+ * client performs its own TLS handshake end-to-end with the upstream.
28
+ *
29
+ * Use for upstreams the proxy must not re-originate: mTLS services
30
+ * (only the in-sandbox client holds the client certificate) and
31
+ * certificate-pinning clients that reject the MITM CA. Note that
32
+ * `filterRequest` and `mutateHeaders` never see the HTTPS traffic to
33
+ * these hosts; plain-HTTP proxy requests to them are unaffected (those
34
+ * are readable without termination and keep the normal request pipeline).
35
+ *
36
+ * Absent, or returning true, means today's behaviour: terminate.
37
+ */
38
+ shouldTerminateTLS?(hostname: string, port: number): boolean;
22
39
  /**
23
40
  * Per-request filter; runs on plain-HTTP proxy requests and on terminated
24
41
  * HTTPS requests. See request-filter.ts.
25
42
  */
26
43
  filterRequest?: FilterRequestCallback;
44
+ /**
45
+ * Mutate forwarded headers on the TLS-terminated path, after the allow
46
+ * decision and before the upstream request is built. The upstream leg is
47
+ * always cert-verified (rejectUnauthorized defaults to true), so the TLS
48
+ * handshake fails before any mutated header bytes reach an unverified
49
+ * server. See {@link MutateForwardedHeaders}.
50
+ */
51
+ mutateHeaders?: MutateForwardedHeaders;
52
+ /**
53
+ * Mutate forwarded headers on the plain-HTTP path. Separate from
54
+ * `mutateHeaders` so callers can wire the TLS path only — credential
55
+ * injection over plaintext is opt-in.
56
+ */
57
+ mutateHeadersPlaintext?: MutateForwardedHeaders;
27
58
  /**
28
59
  * Additional trusted CA(s) for the terminating proxy's outbound TLS leg.
29
60
  * Unset → system roots + NODE_EXTRA_CA_CERTS. Primarily a test seam.
@@ -1 +1 @@
1
- {"version":3,"file":"http-proxy.d.ts","sourceRoot":"","sources":["../../src/sandbox/http-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,KAAK,EAAE,MAAM,EAAY,MAAM,aAAa,CAAA;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAOvC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,qBAAqB,CAAA;AAK5B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAY5D,MAAM,WAAW,sBAAsB;IACrC,MAAM,CACJ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,MAAM,GACtB,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAA;IAE7B;;;;OAIG;IACH,iBAAiB,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IAEpD;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;;OAGG;IACH,aAAa,CAAC,EAAE,qBAAqB,CAAA;IAErC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAA;IAEjE;;;;OAIG;IACH,WAAW,CAAC,EAAE,mBAAmB,CAAA;IAEjC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,MAAM,CA8T7E"}
1
+ {"version":3,"file":"http-proxy.d.ts","sourceRoot":"","sources":["../../src/sandbox/http-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,KAAK,EAAE,MAAM,EAAY,MAAM,aAAa,CAAA;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAOvC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC5B,MAAM,qBAAqB,CAAA;AAK5B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAY5D,MAAM,WAAW,sBAAsB;IACrC,MAAM,CACJ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,MAAM,GACtB,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAA;IAE7B;;;;OAIG;IACH,iBAAiB,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IAEpD;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;;;;;;;;;;;;;;OAeG;IACH,kBAAkB,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;IAE5D;;;OAGG;IACH,aAAa,CAAC,EAAE,qBAAqB,CAAA;IAErC;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,sBAAsB,CAAA;IAEtC;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,sBAAsB,CAAA;IAE/C;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAA;IAEjE;;;;OAIG;IACH,WAAW,CAAC,EAAE,mBAAmB,CAAA;IAEjC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,MAAM,CA0U7E"}
@@ -65,7 +65,8 @@ export function createHttpProxyServer(options) {
65
65
  // (tlsTerminate and mitmProxy are mutually exclusive at the config
66
66
  // layer, so the first two never both apply.)
67
67
  let wrote200 = false;
68
- if (options.mitmCA) {
68
+ if (options.mitmCA &&
69
+ (options.shouldTerminateTLS?.(hostname, port) ?? true)) {
69
70
  if (clientGone)
70
71
  return;
71
72
  // We can only terminate TLS. CONNECT also carries non-TLS streams —
@@ -81,12 +82,18 @@ export function createHttpProxyServer(options) {
81
82
  if (clientGone)
82
83
  return;
83
84
  if (peeked.isTLS) {
84
- terminateAndForward(options.mitmCA, options.filterRequest, socket, peeked.head, { hostname, port, upstreamCA: options.tlsTerminateUpstreamCA });
85
+ terminateAndForward(options.mitmCA, options.filterRequest, options.mutateHeaders, socket, peeked.head, { hostname, port, upstreamCA: options.tlsTerminateUpstreamCA });
85
86
  return;
86
87
  }
87
88
  logForDebugging(`[tls-terminate] non-TLS bytes on CONNECT ${hostname}:${port}; opaque-tunnelling`);
88
89
  head = peeked.head;
89
90
  }
91
+ else if (options.mitmCA) {
92
+ // Per-host termination opt-out: the policy exempts this host (mTLS
93
+ // upstream, cert-pinning client), so skip the MITM entirely and
94
+ // take the opaque tunnel below, exactly as if mitmCA were unset.
95
+ logForDebugging(`[tls-terminate] policy exempts ${hostname}:${port}; opaque-tunnelling`);
96
+ }
90
97
  const mitmSocketPath = options.getMitmSocketPath?.(hostname);
91
98
  const parentUrl = !mitmSocketPath &&
92
99
  options.parentProxy &&
@@ -184,6 +191,7 @@ export function createHttpProxyServer(options) {
184
191
  if (req.socket.destroyed)
185
192
  return;
186
193
  const fwdHeaders = { ...stripHopByHop(req.headers), host: url.host };
194
+ options.mutateHeadersPlaintext?.(fwdHeaders, hostname);
187
195
  // Decide upstream route: MITM unix socket > parent HTTP proxy > direct.
188
196
  const mitmSocketPath = options.getMitmSocketPath?.(hostname);
189
197
  const parentUrl = !mitmSocketPath &&
@@ -1 +1 @@
1
- {"version":3,"file":"http-proxy.js","sourceRoot":"","sources":["../../src/sandbox/http-proxy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"http-proxy.js","sourceRoot":"","sources":["../../src/sandbox/http-proxy.ts"],"names":[],"mappings":"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"}
@@ -22,6 +22,23 @@ export interface LinuxSandboxParams {
22
22
  caCertPath?: string;
23
23
  readConfig?: FsReadRestrictionConfig;
24
24
  writeConfig?: FsWriteRestrictionConfig;
25
+ /** Environment variable names to unset inside the sandbox (bwrap --unsetenv) */
26
+ unsetEnvVars?: string[];
27
+ /** Environment variables to set inside the sandbox (bwrap --setenv NAME VALUE) */
28
+ setEnvVars?: Record<string, string>;
29
+ /**
30
+ * Whole-file credential masks: bind fakePath (sentinel content) over
31
+ * realPath read-only so the sandbox reads the sentinel.
32
+ */
33
+ maskedFileBinds?: Array<{
34
+ realPath: string;
35
+ fakePath: string;
36
+ }>;
37
+ /**
38
+ * Host directory holding the fake files. Ro-bound over itself so the
39
+ * sandbox cannot write the bind sources even if allowWrite covers it.
40
+ */
41
+ maskedFileStoreDir?: string;
25
42
  enableWeakerNestedSandbox?: boolean;
26
43
  allowAllUnixSockets?: boolean;
27
44
  binShell?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"linux-sandbox-utils.d.ts","sourceRoot":"","sources":["../../src/sandbox/linux-sandbox-utils.ts"],"names":[],"mappings":"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"}
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,gEAAgE;IAChE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,uBAAuB,CAAA;IACpC,WAAW,CAAC,EAAE,wBAAwB,CAAA;IACtC,gFAAgF;IAChF,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,kFAAkF;IAClF,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC;;;OAGG;IACH,eAAe,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC/D;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,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,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,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;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAWD;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,CAAC,EAAE,sBAAsB,GAC5B,qBAAqB,CAWvB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,CAAC,EAAE,sBAAsB,GAC5B,sBAAsB,CA6BxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,EACtB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,yBAAyB,CAAC,CAmJpC;AA0hBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,MAAM,CAAC,CAoRjB"}
@@ -365,6 +365,8 @@ export async function initializeLinuxNetworkBridge(httpProxyPort, socksProxyPort
365
365
  const socat = socatPath ?? 'socat';
366
366
  const socketId = randomBytes(8).toString('hex');
367
367
  const httpSocketPath = join(tmpdir(), `claude-http-${socketId}.sock`);
368
+ // Only allocated when ports differ; in the mux case the SOCKS side
369
+ // reuses httpSocketPath.
368
370
  const socksSocketPath = join(tmpdir(), `claude-socks-${socketId}.sock`);
369
371
  // Start HTTP bridge
370
372
  const httpSocatArgs = [
@@ -390,34 +392,48 @@ export async function initializeLinuxNetworkBridge(httpProxyPort, socksProxyPort
390
392
  if (!httpBridgeProcess.pid) {
391
393
  throw new Error('Failed to start HTTP bridge process');
392
394
  }
393
- // Start SOCKS bridge
394
- const socksSocatArgs = [
395
- `UNIX-LISTEN:${socksSocketPath},fork,reuseaddr`,
396
- `TCP:localhost:${socksProxyPort},keepalive,keepidle=10,keepintvl=5,keepcnt=3`,
397
- ];
398
- logForDebugging(`Starting SOCKS bridge: ${socat} ${socksSocatArgs.join(' ')}`);
399
- const socksBridgeProcess = spawn(socat, socksSocatArgs, {
400
- stdio: 'ignore',
401
- });
402
- // Add error and exit handlers to monitor bridge health — registered
403
- // before the !pid check for the same reason as the HTTP bridge above.
404
- socksBridgeProcess.on('error', err => {
405
- logForDebugging(`SOCKS bridge process error: ${err}`, { level: 'error' });
406
- });
407
- socksBridgeProcess.on('exit', (code, signal) => {
408
- logForDebugging(`SOCKS bridge process exited with code ${code}, signal ${signal}`, { level: code === 0 ? 'info' : 'error' });
409
- });
410
- if (!socksBridgeProcess.pid) {
411
- // Clean up HTTP bridge
412
- if (httpBridgeProcess.pid) {
413
- try {
414
- process.kill(httpBridgeProcess.pid, 'SIGTERM');
415
- }
416
- catch {
417
- // Ignore errors
395
+ // SOCKS bridge: when the host serves both protocols on one port (the mux),
396
+ // a second socat to the same TCP target is redundant — reuse the HTTP
397
+ // bridge's process and socket path. Downstream consumers
398
+ // (LinuxNetworkBridgeContext, in-sandbox socat, cleanup) treat duplicate
399
+ // refs idempotently. A separate bridge is only spawned when the ports
400
+ // differ (external proxy override).
401
+ let socksBridgeProcess;
402
+ let socksSockPath;
403
+ if (socksProxyPort === httpProxyPort) {
404
+ socksBridgeProcess = httpBridgeProcess;
405
+ socksSockPath = httpSocketPath;
406
+ }
407
+ else {
408
+ socksSockPath = socksSocketPath;
409
+ const socksSocatArgs = [
410
+ `UNIX-LISTEN:${socksSocketPath},fork,reuseaddr`,
411
+ `TCP:localhost:${socksProxyPort},keepalive,keepidle=10,keepintvl=5,keepcnt=3`,
412
+ ];
413
+ logForDebugging(`Starting SOCKS bridge: ${socat} ${socksSocatArgs.join(' ')}`);
414
+ socksBridgeProcess = spawn(socat, socksSocatArgs, {
415
+ stdio: 'ignore',
416
+ });
417
+ // Add error and exit handlers to monitor bridge health — registered
418
+ // before the !pid check for the same reason as the HTTP bridge above.
419
+ socksBridgeProcess.on('error', err => {
420
+ logForDebugging(`SOCKS bridge process error: ${err}`, { level: 'error' });
421
+ });
422
+ socksBridgeProcess.on('exit', (code, signal) => {
423
+ logForDebugging(`SOCKS bridge process exited with code ${code}, signal ${signal}`, { level: code === 0 ? 'info' : 'error' });
424
+ });
425
+ if (!socksBridgeProcess.pid) {
426
+ // Clean up HTTP bridge
427
+ if (httpBridgeProcess.pid) {
428
+ try {
429
+ process.kill(httpBridgeProcess.pid, 'SIGTERM');
430
+ }
431
+ catch {
432
+ // Ignore errors
433
+ }
418
434
  }
435
+ throw new Error('Failed to start SOCKS bridge process');
419
436
  }
420
- throw new Error('Failed to start SOCKS bridge process');
421
437
  }
422
438
  // Wait for both sockets to be ready
423
439
  const maxAttempts = 5;
@@ -430,7 +446,7 @@ export async function initializeLinuxNetworkBridge(httpProxyPort, socksProxyPort
430
446
  }
431
447
  try {
432
448
  // fs already imported
433
- if (fs.existsSync(httpSocketPath) && fs.existsSync(socksSocketPath)) {
449
+ if (fs.existsSync(httpSocketPath) && fs.existsSync(socksSockPath)) {
434
450
  logForDebugging(`Linux bridges ready after ${i + 1} attempts`);
435
451
  break;
436
452
  }
@@ -464,7 +480,7 @@ export async function initializeLinuxNetworkBridge(httpProxyPort, socksProxyPort
464
480
  }
465
481
  return {
466
482
  httpSocketPath,
467
- socksSocketPath,
483
+ socksSocketPath: socksSockPath,
468
484
  httpBridgeProcess,
469
485
  socksBridgeProcess,
470
486
  httpProxyPort,
@@ -521,6 +537,30 @@ function buildSandboxCommand(httpSocketPath, socksSocketPath, userCommand, apply
521
537
  return `${shellPath} -c ${shellquote.quote([innerScript])}`;
522
538
  }
523
539
  }
540
+ /**
541
+ * bwrap cannot create a file bind mount point over a destination that is
542
+ * itself a symlink — `--ro-bind /dev/null <symlink>` fails with "Can't create
543
+ * file at <path>" and the whole command refuses to start. File read-deny
544
+ * binds therefore target the symlink's resolved target instead: reads
545
+ * through the symlink resolve to that target inside the mount namespace, so
546
+ * the denied content stays covered. This matters for credential dotfiles
547
+ * (~/.netrc, ~/.npmrc, …) that are commonly symlinks into a dotfile
548
+ * manager's directory. Directory denies (`--tmpfs`) are left on the original
549
+ * path: bwrap accepts those, and rewriting them would break allowRead
550
+ * carve-outs expressed against the symlink path (e.g. /bin on usr-merged
551
+ * systems).
552
+ */
553
+ function resolveSymlinkDenyDest(normalizedPath) {
554
+ try {
555
+ if (fs.lstatSync(normalizedPath).isSymbolicLink()) {
556
+ return fs.realpathSync(normalizedPath);
557
+ }
558
+ }
559
+ catch {
560
+ // Dangling symlink or vanished path — keep the original.
561
+ }
562
+ return normalizedPath;
563
+ }
524
564
  /**
525
565
  * Mount a tmpfs over a read-denied directory, then restore the allowed write
526
566
  * paths and allowRead paths the tmpfs just wiped. Used by the denyRead loop
@@ -563,7 +603,7 @@ function pushReadDenyDirMounts(args, normalizedPath, allowedWritePaths, readAllo
563
603
  /**
564
604
  * Generate filesystem bind mount arguments for bwrap
565
605
  */
566
- async function generateFilesystemArgs(readConfig, writeConfig, ripgrepConfig = { command: 'rg' }, mandatoryDenySearchDepth = DEFAULT_MANDATORY_DENY_SEARCH_DEPTH, allowGitConfig = false, abortSignal) {
606
+ async function generateFilesystemArgs(readConfig, writeConfig, maskedFileBinds, maskedFileStoreDir, ripgrepConfig = { command: 'rg' }, mandatoryDenySearchDepth = DEFAULT_MANDATORY_DENY_SEARCH_DEPTH, allowGitConfig = false, abortSignal) {
567
607
  const args = [];
568
608
  // fs already imported
569
609
  // Collect normalized allowed write paths. Populated in the writeConfig
@@ -712,9 +752,12 @@ async function generateFilesystemArgs(readConfig, writeConfig, ripgrepConfig = {
712
752
  // Handle read restrictions by mounting tmpfs over denied paths
713
753
  const readDenyPaths = [];
714
754
  const readAllowPaths = (readConfig?.allowWithinDeny || []).map(p => normalizePathForSandbox(p));
715
- // Files masked by --ro-bind /dev/null below. Used to filter denyWriteArgs so
716
- // that --ro-bind <host> <host> doesn't undo the mask.
717
- const maskedFiles = new Set();
755
+ // Files masked by --ro-bind <source> <dest> below. Map of dest source
756
+ // (/dev/null for read-deny, the sentinel fake for credential mask). Used
757
+ // to filter denyWriteArgs so that --ro-bind <host> <host> doesn't undo
758
+ // the mask, and to re-apply the correct source if a denyWrite ancestor
759
+ // bind re-exposes the dest.
760
+ const maskedFiles = new Map();
718
761
  // Directories masked by --tmpfs below, in emission (shallow-first) order.
719
762
  // Used to filter denyWriteArgs the same way: a dir in both deny lists must
720
763
  // not get its host contents re-bound on top of its own tmpfs.
@@ -739,7 +782,10 @@ async function generateFilesystemArgs(readConfig, writeConfig, ripgrepConfig = {
739
782
  // Always hide /etc/ssh/ssh_config.d to avoid permission issues with OrbStack
740
783
  // SSH is very strict about config file permissions and ownership, and they can
741
784
  // appear wrong inside the sandbox causing "Bad owner or permissions" errors
742
- if (fs.existsSync('/etc/ssh/ssh_config.d')) {
785
+ //
786
+ // Skipped when readConfig is undefined (filesystem.disabled): no read
787
+ // policy means no implicit read denies either.
788
+ if (readConfig && fs.existsSync('/etc/ssh/ssh_config.d')) {
743
789
  readDenyPaths.push('/etc/ssh/ssh_config.d');
744
790
  }
745
791
  // Normalize then sort shallow-first so tmpfs over ancestor dirs lands before
@@ -767,11 +813,29 @@ async function generateFilesystemArgs(readConfig, writeConfig, ripgrepConfig = {
767
813
  logForDebugging(`[Sandbox Linux] Skipping read deny for re-allowed path: ${normalizedPath}`);
768
814
  continue;
769
815
  }
770
- // For files, bind /dev/null instead of tmpfs
771
- args.push('--ro-bind', '/dev/null', normalizedPath);
772
- maskedFiles.add(normalizedPath);
816
+ // For files, bind /dev/null instead of tmpfs. bwrap rejects symlink
817
+ // bind destinations, so the deny bind lands on the resolved target.
818
+ const denyDest = resolveSymlinkDenyDest(normalizedPath);
819
+ args.push('--ro-bind', '/dev/null', denyDest);
820
+ maskedFiles.set(denyDest, '/dev/null');
821
+ maskedFiles.set(normalizedPath, '/dev/null');
773
822
  }
774
823
  }
824
+ // Whole-file credential masks: same bind shape as a file read-deny,
825
+ // but the source is the sentinel-content fake instead of /dev/null.
826
+ // realPath was already normalized (tilde-expanded, realpath'd) by the
827
+ // caller; resolveSymlinkDenyDest covers the symlinked-credential case
828
+ // for the same reason as above. The fake's parent dir is explicitly
829
+ // ro-bound at the end of this function, so the bind source is never
830
+ // writable from inside the sandbox. Adding the dest to maskedFiles
831
+ // ensures a later denyWrite ro-bind over the same path doesn't undo
832
+ // the mask.
833
+ for (const { realPath, fakePath } of maskedFileBinds ?? []) {
834
+ const dest = resolveSymlinkDenyDest(realPath);
835
+ args.push('--ro-bind', fakePath, dest);
836
+ maskedFiles.set(dest, fakePath);
837
+ maskedFiles.set(realPath, fakePath);
838
+ }
775
839
  // Emitting denyWrite last means these ro-binds layer on top of any write
776
840
  // paths the denyRead loop just re-bound. Before this ordering, tmpfs over
777
841
  // an ancestor of cwd would wipe the .git/hooks protection. But skip any
@@ -816,14 +880,32 @@ async function generateFilesystemArgs(readConfig, writeConfig, ripgrepConfig = {
816
880
  pushReadDenyDirMounts(args, tmpfsDir, allowedWritePaths, readAllowPaths);
817
881
  }
818
882
  }
819
- // Same problem for read-denied files: the /dev/null mask landed before the
820
- // denyWrite ancestor bind, so the real file is back. Re-apply the mask.
821
- for (const maskedFile of maskedFiles) {
883
+ // Same problem for masked files: the mask landed before the denyWrite
884
+ // ancestor bind, so the real file is back. Re-apply the mask with its
885
+ // original source (/dev/null for read-deny, the fake for credential mask).
886
+ for (const [maskedFile, source] of maskedFiles) {
822
887
  if (emittedDenyWriteDests.some(dest => maskedFile.startsWith(dest + '/'))) {
823
- logForDebugging(`[Sandbox Linux] Re-applying denyRead file mask re-exposed by denyWrite bind: ${maskedFile}`);
824
- args.push('--ro-bind', '/dev/null', maskedFile);
888
+ // maskedFiles holds both the symlink path and its resolved target so
889
+ // the denyWrite skip-check above matches either. Re-emission must go
890
+ // to the target only — bwrap rejects a symlink bind dest (see
891
+ // resolveSymlinkDenyDest), and the target is masked independently:
892
+ // either its original mask survived (target outside this denyWrite
893
+ // ancestor) or its own iteration re-emits it here.
894
+ if (resolveSymlinkDenyDest(maskedFile) !== maskedFile)
895
+ continue;
896
+ logForDebugging(`[Sandbox Linux] Re-applying file mask re-exposed by denyWrite bind: ${maskedFile}`);
897
+ args.push('--ro-bind', source, maskedFile);
825
898
  }
826
899
  }
900
+ // INVARIANT: the fake-file store directory must never be writable from
901
+ // inside the sandbox. If it were, a sandboxed process could plant a
902
+ // symlink at a fake path and a later host-side write() would follow it,
903
+ // or replace a fake's content so the bind exposes attacker bytes. Emit
904
+ // last so it overlays any earlier --bind that covers the store dir
905
+ // (e.g. allowWrite: ['/tmp'] when the store is under os.tmpdir()).
906
+ if (maskedFileStoreDir !== undefined) {
907
+ args.push('--ro-bind', maskedFileStoreDir, maskedFileStoreDir);
908
+ }
827
909
  return args;
828
910
  }
829
911
  /**
@@ -875,16 +957,20 @@ async function generateFilesystemArgs(readConfig, writeConfig, ripgrepConfig = {
875
957
  * Dependencies are checked by checkLinuxDependencies() before enabling the sandbox.
876
958
  */
877
959
  export async function wrapCommandWithSandboxLinux(params) {
878
- const { command, needsNetworkRestriction, httpSocketPath, socksSocketPath, httpProxyPort, socksProxyPort, proxyAuthToken, caCertPath, readConfig, writeConfig, enableWeakerNestedSandbox, allowAllUnixSockets, binShell, ripgrepConfig = { command: 'rg' }, mandatoryDenySearchDepth = DEFAULT_MANDATORY_DENY_SEARCH_DEPTH, allowGitConfig = false, seccompConfig, bwrapPath, socatPath, abortSignal, } = params;
960
+ const { command, needsNetworkRestriction, httpSocketPath, socksSocketPath, httpProxyPort, socksProxyPort, proxyAuthToken, caCertPath, readConfig, writeConfig, unsetEnvVars, setEnvVars, maskedFileBinds, maskedFileStoreDir, enableWeakerNestedSandbox, allowAllUnixSockets, binShell, ripgrepConfig = { command: 'rg' }, mandatoryDenySearchDepth = DEFAULT_MANDATORY_DENY_SEARCH_DEPTH, allowGitConfig = false, seccompConfig, bwrapPath, socatPath, abortSignal, } = params;
879
961
  // Determine if we have restrictions to apply
880
962
  // Read: denyOnly pattern - empty array means no restrictions
881
963
  // Write: allowOnly pattern - undefined means no restrictions, any config means restrictions
882
- const hasReadRestrictions = readConfig && readConfig.denyOnly.length > 0;
964
+ const hasReadRestrictions = (readConfig && readConfig.denyOnly.length > 0) ||
965
+ (maskedFileBinds !== undefined && maskedFileBinds.length > 0);
883
966
  const hasWriteRestrictions = writeConfig !== undefined;
967
+ const hasEnvRestrictions = (unsetEnvVars !== undefined && unsetEnvVars.length > 0) ||
968
+ (setEnvVars !== undefined && Object.keys(setEnvVars).length > 0);
884
969
  // Check if we need any sandboxing
885
970
  if (!needsNetworkRestriction &&
886
971
  !hasReadRestrictions &&
887
- !hasWriteRestrictions) {
972
+ !hasWriteRestrictions &&
973
+ !hasEnvRestrictions) {
888
974
  return command;
889
975
  }
890
976
  // Mark this sandbox invocation as active. cleanupBwrapMountPoints() will
@@ -913,6 +999,21 @@ export async function wrapCommandWithSandboxLinux(params) {
913
999
  else {
914
1000
  logForDebugging('[Sandbox Linux] Skipping seccomp filter - allowAllUnixSockets is enabled');
915
1001
  }
1002
+ // ========== ENV RESTRICTIONS ==========
1003
+ // Drop denied credential env vars from the inherited environment. Emitted
1004
+ // before the proxy --setenv flags below: bwrap applies env operations in
1005
+ // argument order, so SRT's own proxy plumbing vars survive even if a
1006
+ // caller lists one of them as a denied credential.
1007
+ if (hasEnvRestrictions) {
1008
+ for (const name of unsetEnvVars ?? []) {
1009
+ bwrapArgs.push('--unsetenv', name);
1010
+ }
1011
+ // Masked credentials override the inherited real value with a
1012
+ // sentinel; bwrap --setenv replaces any inherited value of NAME.
1013
+ for (const [name, value] of Object.entries(setEnvVars ?? {})) {
1014
+ bwrapArgs.push('--setenv', name, value);
1015
+ }
1016
+ }
916
1017
  // ========== NETWORK RESTRICTIONS ==========
917
1018
  if (needsNetworkRestriction) {
918
1019
  // Always unshare network namespace to isolate network access
@@ -933,13 +1034,18 @@ export async function wrapCommandWithSandboxLinux(params) {
933
1034
  }
934
1035
  // Bind both sockets into the sandbox
935
1036
  bwrapArgs.push('--bind', httpSocketPath, httpSocketPath);
936
- bwrapArgs.push('--bind', socksSocketPath, socksSocketPath);
1037
+ // When the mux serves both protocols, socksSocketPath is the same
1038
+ // file as httpSocketPath; bwrap rejects a duplicate --bind of the
1039
+ // same source→target.
1040
+ if (socksSocketPath !== httpSocketPath) {
1041
+ bwrapArgs.push('--bind', socksSocketPath, socksSocketPath);
1042
+ }
937
1043
  // Add proxy environment variables
938
1044
  // HTTP_PROXY points to the socat listener inside the sandbox (port 3128)
939
1045
  // which forwards to the Unix socket that bridges to the host's proxy server
940
1046
  const proxyEnv = generateProxyEnvVars(3128, // Internal HTTP listener port
941
1047
  1080, // Internal SOCKS listener port
942
- caCertPath, proxyAuthToken);
1048
+ caCertPath, proxyAuthToken, writeConfig === undefined);
943
1049
  bwrapArgs.push(...proxyEnv.flatMap((env) => {
944
1050
  const firstEq = env.indexOf('=');
945
1051
  const key = env.slice(0, firstEq);
@@ -958,7 +1064,7 @@ export async function wrapCommandWithSandboxLinux(params) {
958
1064
  // If no sockets provided, network is completely blocked (--unshare-net without proxy)
959
1065
  }
960
1066
  // ========== FILESYSTEM RESTRICTIONS ==========
961
- const fsArgs = await generateFilesystemArgs(readConfig, writeConfig, ripgrepConfig, mandatoryDenySearchDepth, allowGitConfig, abortSignal);
1067
+ const fsArgs = await generateFilesystemArgs(readConfig, writeConfig, maskedFileBinds, maskedFileStoreDir, ripgrepConfig, mandatoryDenySearchDepth, allowGitConfig, abortSignal);
962
1068
  bwrapArgs.push(...fsArgs);
963
1069
  // Always bind /dev
964
1070
  bwrapArgs.push('--dev', '/dev');
@@ -1022,6 +1128,8 @@ export async function wrapCommandWithSandboxLinux(params) {
1022
1128
  restrictions.push('network');
1023
1129
  if (hasReadRestrictions || hasWriteRestrictions)
1024
1130
  restrictions.push('filesystem');
1131
+ if (hasEnvRestrictions)
1132
+ restrictions.push('env');
1025
1133
  if (applySeccompPrefix)
1026
1134
  restrictions.push('seccomp(unix-block)');
1027
1135
  logForDebugging(`[Sandbox Linux] Wrapped command with bwrap (${restrictions.join(', ')} restrictions)`);