pi-codex-auto-review 0.1.0
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/LICENSE +201 -0
- package/NOTICE +10 -0
- package/README.md +77 -0
- package/dist/approvals.d.ts +72 -0
- package/dist/approvals.js +167 -0
- package/dist/approvals.js.map +1 -0
- package/dist/audit.d.ts +28 -0
- package/dist/audit.js +40 -0
- package/dist/audit.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +70 -0
- package/dist/cli.js.map +1 -0
- package/dist/context-files.d.ts +14 -0
- package/dist/context-files.js +113 -0
- package/dist/context-files.js.map +1 -0
- package/dist/contracts.d.ts +258 -0
- package/dist/contracts.js +102 -0
- package/dist/contracts.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +106 -0
- package/dist/index.js.map +1 -0
- package/dist/native/darwin-arm64/artifact.json +5 -0
- package/dist/native/darwin-arm64/pi-guard-execpolicy +0 -0
- package/dist/native/linux-x64/artifact.json +5 -0
- package/dist/native/linux-x64/pi-guard-execpolicy +0 -0
- package/dist/policy/domains.d.ts +5 -0
- package/dist/policy/domains.js +18 -0
- package/dist/policy/domains.js.map +1 -0
- package/dist/policy/index.d.ts +56 -0
- package/dist/policy/index.js +304 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/paths.d.ts +5 -0
- package/dist/policy/paths.js +54 -0
- package/dist/policy/paths.js.map +1 -0
- package/dist/policy/rules.d.ts +36 -0
- package/dist/policy/rules.js +61 -0
- package/dist/policy/rules.js.map +1 -0
- package/dist/policy/shell.d.ts +14 -0
- package/dist/policy/shell.js +122 -0
- package/dist/policy/shell.js.map +1 -0
- package/dist/reports.d.ts +21 -0
- package/dist/reports.js +42 -0
- package/dist/reports.js.map +1 -0
- package/dist/review/context.d.ts +25 -0
- package/dist/review/context.js +108 -0
- package/dist/review/context.js.map +1 -0
- package/dist/review/investigation.d.ts +39 -0
- package/dist/review/investigation.js +36 -0
- package/dist/review/investigation.js.map +1 -0
- package/dist/review/lifecycle.d.ts +29 -0
- package/dist/review/lifecycle.js +71 -0
- package/dist/review/lifecycle.js.map +1 -0
- package/dist/review/policy.d.ts +4 -0
- package/dist/review/policy.js +15 -0
- package/dist/review/policy.js.map +1 -0
- package/dist/review/upstream-policy.d.ts +2 -0
- package/dist/review/upstream-policy.js +210 -0
- package/dist/review/upstream-policy.js.map +1 -0
- package/dist/reviewer.d.ts +45 -0
- package/dist/reviewer.js +148 -0
- package/dist/reviewer.js.map +1 -0
- package/dist/sandbox/broker.d.ts +1 -0
- package/dist/sandbox/broker.js +135 -0
- package/dist/sandbox/broker.js.map +1 -0
- package/dist/sandbox/config.d.ts +5 -0
- package/dist/sandbox/config.js +91 -0
- package/dist/sandbox/config.js.map +1 -0
- package/dist/sandbox/executor.d.ts +20 -0
- package/dist/sandbox/executor.js +144 -0
- package/dist/sandbox/executor.js.map +1 -0
- package/dist/sandbox/hard-links.d.ts +4 -0
- package/dist/sandbox/hard-links.js +145 -0
- package/dist/sandbox/hard-links.js.map +1 -0
- package/dist/sandbox/linux-read-paths.d.ts +7 -0
- package/dist/sandbox/linux-read-paths.js +47 -0
- package/dist/sandbox/linux-read-paths.js.map +1 -0
- package/dist/sandbox/paths.d.ts +3 -0
- package/dist/sandbox/paths.js +10 -0
- package/dist/sandbox/paths.js.map +1 -0
- package/dist/sandbox/runtime-write-paths.d.ts +2 -0
- package/dist/sandbox/runtime-write-paths.js +8 -0
- package/dist/sandbox/runtime-write-paths.js.map +1 -0
- package/dist/sandbox/seccomp.d.ts +5 -0
- package/dist/sandbox/seccomp.js +16 -0
- package/dist/sandbox/seccomp.js.map +1 -0
- package/dist/sandbox/worker.d.ts +1 -0
- package/dist/sandbox/worker.js +73 -0
- package/dist/sandbox/worker.js.map +1 -0
- package/dist/signals.d.ts +10 -0
- package/dist/signals.js +21 -0
- package/dist/signals.js.map +1 -0
- package/dist/startup.d.ts +22 -0
- package/dist/startup.js +100 -0
- package/dist/startup.js.map +1 -0
- package/dist/tools/controller.d.ts +63 -0
- package/dist/tools/controller.js +286 -0
- package/dist/tools/controller.js.map +1 -0
- package/dist/tools/external.d.ts +30 -0
- package/dist/tools/external.js +24 -0
- package/dist/tools/external.js.map +1 -0
- package/dist/tools/mcp.d.ts +17 -0
- package/dist/tools/mcp.js +186 -0
- package/dist/tools/mcp.js.map +1 -0
- package/docs/publishing.md +73 -0
- package/docs/security/dependencies.md +43 -0
- package/docs/testing/auto-review-protection.md +130 -0
- package/docs/usage.md +217 -0
- package/native/execpolicy/LICENSE +201 -0
- package/native/execpolicy/NOTICE +6 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/LICENSE +201 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/README.md +901 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/cli.d.ts +3 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/cli.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/cli.js +472 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/cli.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/index.d.ts +19 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/index.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/index.js +17 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/index.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/address.d.ts +52 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/address.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/address.js +153 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/address.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/aws-sigv4.d.ts +164 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/aws-sigv4.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/aws-sigv4.js +246 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/aws-sigv4.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/body-substitution.d.ts +58 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/body-substitution.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/body-substitution.js +128 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/body-substitution.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-aws-pairs.d.ts +124 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-aws-pairs.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-aws-pairs.js +258 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-aws-pairs.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-decode.d.ts +87 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-decode.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-decode.js +138 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-decode.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-extract.d.ts +67 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-extract.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-extract.js +113 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-extract.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-mask-env.d.ts +70 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-mask-env.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-mask-env.js +171 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-mask-env.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-mask-files.d.ts +120 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-mask-files.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-mask-files.js +281 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-mask-files.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-sentinel.d.ts +108 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-sentinel.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-sentinel.js +208 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/credential-sentinel.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/domain-pattern.d.ts +82 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/domain-pattern.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/domain-pattern.js +155 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/domain-pattern.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/generate-seccomp-filter.d.ts +44 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/generate-seccomp-filter.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/generate-seccomp-filter.js +220 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/generate-seccomp-filter.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/http-proxy.d.ts +150 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/http-proxy.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/http-proxy.js +678 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/http-proxy.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/java-proxy-agent.d.ts +32 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/java-proxy-agent.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/java-proxy-agent.js +111 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/java-proxy-agent.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/linux-sandbox-utils.d.ts +305 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/linux-sandbox-utils.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/linux-sandbox-utils.js +2605 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/linux-sandbox-utils.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/linux-violation-monitor.d.ts +55 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/linux-violation-monitor.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/linux-violation-monitor.js +152 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/linux-violation-monitor.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/listen-in-range.d.ts +12 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/listen-in-range.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/listen-in-range.js +43 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/listen-in-range.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/macos-sandbox-utils.d.ts +116 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/macos-sandbox-utils.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/macos-sandbox-utils.js +1195 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/macos-sandbox-utils.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/mitm-ca.d.ts +200 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/mitm-ca.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/mitm-ca.js +443 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/mitm-ca.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/mitm-leaf.d.ts +28 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/mitm-leaf.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/mitm-leaf.js +114 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/mitm-leaf.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/mux-proxy.d.ts +59 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/mux-proxy.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/mux-proxy.js +159 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/mux-proxy.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/parent-proxy.d.ts +147 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/parent-proxy.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/parent-proxy.js +445 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/parent-proxy.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/read-deny-glob.d.ts +17 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/read-deny-glob.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/read-deny-glob.js +163 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/read-deny-glob.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/request-filter.d.ts +83 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/request-filter.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/request-filter.js +212 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/request-filter.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/resolved-address-guard.d.ts +76 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/resolved-address-guard.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/resolved-address-guard.js +221 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/resolved-address-guard.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-config.d.ts +1691 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-config.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-config.js +1233 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-config.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-manager.d.ts +97 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-manager.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-manager.js +1937 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-manager.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-schemas.d.ts +113 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-schemas.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-schemas.js +3 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-schemas.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-utils.d.ts +411 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-utils.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-utils.js +1408 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-utils.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-violation-store.d.ts +37 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-violation-store.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-violation-store.js +125 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/sandbox-violation-store.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/socks-proxy.d.ts +57 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/socks-proxy.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/socks-proxy.js +332 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/socks-proxy.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/tls-terminate-proxy.d.ts +100 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/tls-terminate-proxy.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/tls-terminate-proxy.js +546 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/tls-terminate-proxy.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/windows-sandbox-utils.d.ts +923 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/windows-sandbox-utils.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/windows-sandbox-utils.js +1419 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/sandbox/windows-sandbox-utils.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/config-loader.d.ts +31 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/config-loader.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/config-loader.js +69 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/config-loader.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/debug.d.ts +7 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/debug.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/debug.js +25 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/debug.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/platform.d.ts +15 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/platform.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/platform.js +49 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/platform.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/ripgrep.d.ts +17 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/ripgrep.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/ripgrep.js +37 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/ripgrep.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/shell-quote.d.ts +27 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/shell-quote.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/shell-quote.js +47 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/shell-quote.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/which.d.ts +9 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/which.d.ts.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/which.js +25 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/dist/utils/which.js.map +1 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/package.json +88 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/vendor/java-proxy-agent/build.ts +95 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/vendor/java-proxy-agent/srt-proxy-agent.jar +0 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/vendor/seccomp/arm64/apply-seccomp +0 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/vendor/seccomp/build.ts +69 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/vendor/seccomp/x64/apply-seccomp +0 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/vendor/srt-win/arm64/srt-win.exe +0 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/vendor/srt-win/build.ts +28 -0
- package/node_modules/@anthropic-ai/sandbox-runtime/vendor/srt-win/x64/srt-win.exe +0 -0
- package/node_modules/@pondwader/socks5-server/.github/workflows/ci.yml +27 -0
- package/node_modules/@pondwader/socks5-server/LICENSE +20 -0
- package/node_modules/@pondwader/socks5-server/README.md +151 -0
- package/node_modules/@pondwader/socks5-server/dist/index.d.mts +87 -0
- package/node_modules/@pondwader/socks5-server/dist/index.d.ts +87 -0
- package/node_modules/@pondwader/socks5-server/dist/index.js +346 -0
- package/node_modules/@pondwader/socks5-server/dist/index.mjs +307 -0
- package/node_modules/@pondwader/socks5-server/package.json +31 -0
- package/node_modules/commander/LICENSE +22 -0
- package/node_modules/commander/Readme.md +1157 -0
- package/node_modules/commander/esm.mjs +16 -0
- package/node_modules/commander/index.js +24 -0
- package/node_modules/commander/lib/argument.js +149 -0
- package/node_modules/commander/lib/command.js +2509 -0
- package/node_modules/commander/lib/error.js +39 -0
- package/node_modules/commander/lib/help.js +520 -0
- package/node_modules/commander/lib/option.js +330 -0
- package/node_modules/commander/lib/suggestSimilar.js +101 -0
- package/node_modules/commander/package-support.json +16 -0
- package/node_modules/commander/package.json +84 -0
- package/node_modules/commander/typings/esm.d.mts +3 -0
- package/node_modules/commander/typings/index.d.ts +969 -0
- package/node_modules/node-forge/.editorconfig +17 -0
- package/node_modules/node-forge/.eslintrc.js +24 -0
- package/node_modules/node-forge/.github/workflows/main.yaml +96 -0
- package/node_modules/node-forge/.istanbul.yml +2 -0
- package/node_modules/node-forge/.npmignore +15 -0
- package/node_modules/node-forge/CHANGELOG.md +555 -0
- package/node_modules/node-forge/CONTRIBUTING.md +18 -0
- package/node_modules/node-forge/LICENSE +331 -0
- package/node_modules/node-forge/README.md +2071 -0
- package/node_modules/node-forge/RELEASE.md +19 -0
- package/node_modules/node-forge/SECURITY.md +5 -0
- package/node_modules/node-forge/examples/create-cert.js +110 -0
- package/node_modules/node-forge/examples/create-csr.js +66 -0
- package/node_modules/node-forge/examples/create-pkcs12.js +160 -0
- package/node_modules/node-forge/examples/imap.js +46 -0
- package/node_modules/node-forge/examples/sign-p7.js +115 -0
- package/node_modules/node-forge/examples/tls.js +189 -0
- package/node_modules/node-forge/flash/PooledSocket.as +18 -0
- package/node_modules/node-forge/flash/README.md +48 -0
- package/node_modules/node-forge/flash/SocketEvent.as +36 -0
- package/node_modules/node-forge/flash/SocketPool.as +754 -0
- package/node_modules/node-forge/flash/mod_fsp/README +135 -0
- package/node_modules/node-forge/flash/mod_fsp/mod_fsp.c +415 -0
- package/node_modules/node-forge/flash/package.json +28 -0
- package/node_modules/node-forge/flash/policyserver.js +65 -0
- package/node_modules/node-forge/flash/policyserver.py +112 -0
- package/node_modules/node-forge/flash/swf/SocketPool.swf +0 -0
- package/node_modules/node-forge/karma-sauce.conf.js +79 -0
- package/node_modules/node-forge/karma.conf.js +133 -0
- package/node_modules/node-forge/lib/aes.js +1091 -0
- package/node_modules/node-forge/lib/aesCipherSuites.js +282 -0
- package/node_modules/node-forge/lib/asn1-validator.js +91 -0
- package/node_modules/node-forge/lib/asn1.js +1503 -0
- package/node_modules/node-forge/lib/baseN.js +186 -0
- package/node_modules/node-forge/lib/cipher.js +230 -0
- package/node_modules/node-forge/lib/cipherModes.js +999 -0
- package/node_modules/node-forge/lib/des.js +496 -0
- package/node_modules/node-forge/lib/ed25519.js +1091 -0
- package/node_modules/node-forge/lib/forge.js +13 -0
- package/node_modules/node-forge/lib/form.js +149 -0
- package/node_modules/node-forge/lib/hmac.js +146 -0
- package/node_modules/node-forge/lib/http.js +1346 -0
- package/node_modules/node-forge/lib/index.all.js +16 -0
- package/node_modules/node-forge/lib/index.js +33 -0
- package/node_modules/node-forge/lib/jsbn.js +1294 -0
- package/node_modules/node-forge/lib/kem.js +168 -0
- package/node_modules/node-forge/lib/log.js +319 -0
- package/node_modules/node-forge/lib/md.all.js +13 -0
- package/node_modules/node-forge/lib/md.js +11 -0
- package/node_modules/node-forge/lib/md5.js +289 -0
- package/node_modules/node-forge/lib/mgf.js +12 -0
- package/node_modules/node-forge/lib/mgf1.js +57 -0
- package/node_modules/node-forge/lib/oids.js +180 -0
- package/node_modules/node-forge/lib/pbe.js +1023 -0
- package/node_modules/node-forge/lib/pbkdf2.js +211 -0
- package/node_modules/node-forge/lib/pem.js +237 -0
- package/node_modules/node-forge/lib/pkcs1.js +276 -0
- package/node_modules/node-forge/lib/pkcs12.js +1078 -0
- package/node_modules/node-forge/lib/pkcs7.js +1260 -0
- package/node_modules/node-forge/lib/pkcs7asn1.js +410 -0
- package/node_modules/node-forge/lib/pki.js +102 -0
- package/node_modules/node-forge/lib/prime.js +297 -0
- package/node_modules/node-forge/lib/prime.worker.js +168 -0
- package/node_modules/node-forge/lib/prng.js +419 -0
- package/node_modules/node-forge/lib/pss.js +241 -0
- package/node_modules/node-forge/lib/random.js +191 -0
- package/node_modules/node-forge/lib/rc2.js +410 -0
- package/node_modules/node-forge/lib/rsa.js +1973 -0
- package/node_modules/node-forge/lib/sha1.js +319 -0
- package/node_modules/node-forge/lib/sha256.js +327 -0
- package/node_modules/node-forge/lib/sha512.js +561 -0
- package/node_modules/node-forge/lib/socket.js +287 -0
- package/node_modules/node-forge/lib/ssh.js +236 -0
- package/node_modules/node-forge/lib/tls.js +4282 -0
- package/node_modules/node-forge/lib/tlssocket.js +249 -0
- package/node_modules/node-forge/lib/util.js +2652 -0
- package/node_modules/node-forge/lib/x509.js +3251 -0
- package/node_modules/node-forge/lib/xhr.js +738 -0
- package/node_modules/node-forge/package.json +123 -0
- package/node_modules/node-forge/tests/.eslintrc.js +5 -0
- package/node_modules/node-forge/tests/README.md +4 -0
- package/node_modules/node-forge/tests/benchmarks/aes-speed.js +62 -0
- package/node_modules/node-forge/tests/benchmarks/so-44303784.js +246 -0
- package/node_modules/node-forge/tests/flash/README.md +7 -0
- package/node_modules/node-forge/tests/flash/Test.as +96 -0
- package/node_modules/node-forge/tests/flash/build-flash.xml +7 -0
- package/node_modules/node-forge/tests/flash/index.html +28 -0
- package/node_modules/node-forge/tests/index.html +33 -0
- package/node_modules/node-forge/tests/issues/heartbleed.js +55 -0
- package/node_modules/node-forge/tests/issues/issue-428.html +95 -0
- package/node_modules/node-forge/tests/issues/issue-428.js +375 -0
- package/node_modules/node-forge/tests/karma/index.js +8 -0
- package/node_modules/node-forge/tests/karma/testWorker.js +65 -0
- package/node_modules/node-forge/tests/karma/web-worker-rsa.js +55 -0
- package/node_modules/node-forge/tests/legacy/common.html +65 -0
- package/node_modules/node-forge/tests/legacy/common.js +2199 -0
- package/node_modules/node-forge/tests/legacy/form.html +148 -0
- package/node_modules/node-forge/tests/legacy/form.js +40 -0
- package/node_modules/node-forge/tests/legacy/http.html +235 -0
- package/node_modules/node-forge/tests/legacy/index.html +70 -0
- package/node_modules/node-forge/tests/legacy/keygen.html +113 -0
- package/node_modules/node-forge/tests/legacy/login.css +26 -0
- package/node_modules/node-forge/tests/legacy/loginDemo.html +32 -0
- package/node_modules/node-forge/tests/legacy/loginDemo.js +149 -0
- package/node_modules/node-forge/tests/legacy/performance.html +533 -0
- package/node_modules/node-forge/tests/legacy/result.txt +1 -0
- package/node_modules/node-forge/tests/legacy/socketPool.html +302 -0
- package/node_modules/node-forge/tests/legacy/tasks.html +54 -0
- package/node_modules/node-forge/tests/legacy/tasks.js +378 -0
- package/node_modules/node-forge/tests/legacy/tls.html +389 -0
- package/node_modules/node-forge/tests/legacy/webid.html +89 -0
- package/node_modules/node-forge/tests/legacy/webid.js +313 -0
- package/node_modules/node-forge/tests/legacy/ws-webid.js +120 -0
- package/node_modules/node-forge/tests/legacy/xhr.html +67 -0
- package/node_modules/node-forge/tests/legacy/xhr.js +590 -0
- package/node_modules/node-forge/tests/pocs/ghsa-2328-f5f3-gj25.js +85 -0
- package/node_modules/node-forge/tests/pocs/ghsa-ppp5-5v6c-4jwp.js +166 -0
- package/node_modules/node-forge/tests/pocs/ghsa-q67f-28xg-22rw.js +103 -0
- package/node_modules/node-forge/tests/security/cve-2025-12816.js +75 -0
- package/node_modules/node-forge/tests/security/ghsa-554w-wpv2-vw27.js +81 -0
- package/node_modules/node-forge/tests/security/index.js +3 -0
- package/node_modules/node-forge/tests/server.crt +26 -0
- package/node_modules/node-forge/tests/server.js +87 -0
- package/node_modules/node-forge/tests/server.key +27 -0
- package/node_modules/node-forge/tests/support/task.js +718 -0
- package/node_modules/node-forge/tests/tests.css +61 -0
- package/node_modules/node-forge/tests/unit/aes.js +1498 -0
- package/node_modules/node-forge/tests/unit/asn1.js +1337 -0
- package/node_modules/node-forge/tests/unit/csr.js +129 -0
- package/node_modules/node-forge/tests/unit/des.js +231 -0
- package/node_modules/node-forge/tests/unit/ed25519.js +395 -0
- package/node_modules/node-forge/tests/unit/forge.js +2 -0
- package/node_modules/node-forge/tests/unit/hmac.js +64 -0
- package/node_modules/node-forge/tests/unit/index.html +20 -0
- package/node_modules/node-forge/tests/unit/index.js +27 -0
- package/node_modules/node-forge/tests/unit/jsbn.js +40 -0
- package/node_modules/node-forge/tests/unit/kem.js +167 -0
- package/node_modules/node-forge/tests/unit/md5.js +114 -0
- package/node_modules/node-forge/tests/unit/mgf1.js +16 -0
- package/node_modules/node-forge/tests/unit/pbkdf2.js +182 -0
- package/node_modules/node-forge/tests/unit/pem.js +159 -0
- package/node_modules/node-forge/tests/unit/pkcs1.js +1077 -0
- package/node_modules/node-forge/tests/unit/pkcs12.js +739 -0
- package/node_modules/node-forge/tests/unit/pkcs7.js +792 -0
- package/node_modules/node-forge/tests/unit/random.js +48 -0
- package/node_modules/node-forge/tests/unit/rc2.js +88 -0
- package/node_modules/node-forge/tests/unit/rsa.js +1278 -0
- package/node_modules/node-forge/tests/unit/sha1.js +72 -0
- package/node_modules/node-forge/tests/unit/sha256.js +79 -0
- package/node_modules/node-forge/tests/unit/sha512.js +200 -0
- package/node_modules/node-forge/tests/unit/ssh.js +175 -0
- package/node_modules/node-forge/tests/unit/tls.js +175 -0
- package/node_modules/node-forge/tests/unit/util.js +595 -0
- package/node_modules/node-forge/tests/unit/x509.js +1986 -0
- package/node_modules/node-forge/tests/websockets/server-webid.js +495 -0
- package/node_modules/node-forge/tests/websockets/server-ws.js +158 -0
- package/node_modules/node-forge/webpack-tests.config.js +26 -0
- package/node_modules/node-forge/webpack.config.js +130 -0
- package/node_modules/zod/LICENSE +21 -0
- package/node_modules/zod/README.md +208 -0
- package/node_modules/zod/index.cjs +33 -0
- package/node_modules/zod/index.d.cts +4 -0
- package/node_modules/zod/index.d.ts +4 -0
- package/node_modules/zod/index.js +4 -0
- package/node_modules/zod/package.json +118 -0
- package/node_modules/zod/src/index.ts +4 -0
- package/node_modules/zod/src/v3/ZodError.ts +330 -0
- package/node_modules/zod/src/v3/benchmarks/datetime.ts +58 -0
- package/node_modules/zod/src/v3/benchmarks/discriminatedUnion.ts +80 -0
- package/node_modules/zod/src/v3/benchmarks/index.ts +59 -0
- package/node_modules/zod/src/v3/benchmarks/ipv4.ts +57 -0
- package/node_modules/zod/src/v3/benchmarks/object.ts +69 -0
- package/node_modules/zod/src/v3/benchmarks/primitives.ts +162 -0
- package/node_modules/zod/src/v3/benchmarks/realworld.ts +63 -0
- package/node_modules/zod/src/v3/benchmarks/string.ts +55 -0
- package/node_modules/zod/src/v3/benchmarks/union.ts +80 -0
- package/node_modules/zod/src/v3/errors.ts +13 -0
- package/node_modules/zod/src/v3/external.ts +6 -0
- package/node_modules/zod/src/v3/helpers/enumUtil.ts +17 -0
- package/node_modules/zod/src/v3/helpers/errorUtil.ts +8 -0
- package/node_modules/zod/src/v3/helpers/parseUtil.ts +176 -0
- package/node_modules/zod/src/v3/helpers/partialUtil.ts +34 -0
- package/node_modules/zod/src/v3/helpers/typeAliases.ts +2 -0
- package/node_modules/zod/src/v3/helpers/util.ts +224 -0
- package/node_modules/zod/src/v3/index.ts +4 -0
- package/node_modules/zod/src/v3/locales/en.ts +124 -0
- package/node_modules/zod/src/v3/standard-schema.ts +113 -0
- package/node_modules/zod/src/v3/tests/Mocker.ts +54 -0
- package/node_modules/zod/src/v3/tests/all-errors.test.ts +157 -0
- package/node_modules/zod/src/v3/tests/anyunknown.test.ts +28 -0
- package/node_modules/zod/src/v3/tests/array.test.ts +71 -0
- package/node_modules/zod/src/v3/tests/async-parsing.test.ts +388 -0
- package/node_modules/zod/src/v3/tests/async-refinements.test.ts +46 -0
- package/node_modules/zod/src/v3/tests/base.test.ts +29 -0
- package/node_modules/zod/src/v3/tests/bigint.test.ts +55 -0
- package/node_modules/zod/src/v3/tests/branded.test.ts +53 -0
- package/node_modules/zod/src/v3/tests/catch.test.ts +220 -0
- package/node_modules/zod/src/v3/tests/coerce.test.ts +133 -0
- package/node_modules/zod/src/v3/tests/complex.test.ts +56 -0
- package/node_modules/zod/src/v3/tests/custom.test.ts +31 -0
- package/node_modules/zod/src/v3/tests/date.test.ts +32 -0
- package/node_modules/zod/src/v3/tests/deepmasking.test.ts +186 -0
- package/node_modules/zod/src/v3/tests/default.test.ts +112 -0
- package/node_modules/zod/src/v3/tests/description.test.ts +33 -0
- package/node_modules/zod/src/v3/tests/discriminated-unions.test.ts +315 -0
- package/node_modules/zod/src/v3/tests/enum.test.ts +80 -0
- package/node_modules/zod/src/v3/tests/error.test.ts +551 -0
- package/node_modules/zod/src/v3/tests/firstparty.test.ts +87 -0
- package/node_modules/zod/src/v3/tests/firstpartyschematypes.test.ts +21 -0
- package/node_modules/zod/src/v3/tests/function.test.ts +257 -0
- package/node_modules/zod/src/v3/tests/generics.test.ts +48 -0
- package/node_modules/zod/src/v3/tests/instanceof.test.ts +37 -0
- package/node_modules/zod/src/v3/tests/intersection.test.ts +110 -0
- package/node_modules/zod/src/v3/tests/language-server.source.ts +76 -0
- package/node_modules/zod/src/v3/tests/language-server.test.ts +207 -0
- package/node_modules/zod/src/v3/tests/literal.test.ts +36 -0
- package/node_modules/zod/src/v3/tests/map.test.ts +110 -0
- package/node_modules/zod/src/v3/tests/masking.test.ts +4 -0
- package/node_modules/zod/src/v3/tests/mocker.test.ts +19 -0
- package/node_modules/zod/src/v3/tests/nan.test.ts +21 -0
- package/node_modules/zod/src/v3/tests/nativeEnum.test.ts +87 -0
- package/node_modules/zod/src/v3/tests/nullable.test.ts +42 -0
- package/node_modules/zod/src/v3/tests/number.test.ts +176 -0
- package/node_modules/zod/src/v3/tests/object-augmentation.test.ts +29 -0
- package/node_modules/zod/src/v3/tests/object-in-es5-env.test.ts +29 -0
- package/node_modules/zod/src/v3/tests/object.test.ts +434 -0
- package/node_modules/zod/src/v3/tests/optional.test.ts +42 -0
- package/node_modules/zod/src/v3/tests/parseUtil.test.ts +23 -0
- package/node_modules/zod/src/v3/tests/parser.test.ts +41 -0
- package/node_modules/zod/src/v3/tests/partials.test.ts +243 -0
- package/node_modules/zod/src/v3/tests/pickomit.test.ts +111 -0
- package/node_modules/zod/src/v3/tests/pipeline.test.ts +29 -0
- package/node_modules/zod/src/v3/tests/preprocess.test.ts +186 -0
- package/node_modules/zod/src/v3/tests/primitive.test.ts +440 -0
- package/node_modules/zod/src/v3/tests/promise.test.ts +90 -0
- package/node_modules/zod/src/v3/tests/readonly.test.ts +194 -0
- package/node_modules/zod/src/v3/tests/record.test.ts +171 -0
- package/node_modules/zod/src/v3/tests/recursive.test.ts +197 -0
- package/node_modules/zod/src/v3/tests/refine.test.ts +313 -0
- package/node_modules/zod/src/v3/tests/safeparse.test.ts +27 -0
- package/node_modules/zod/src/v3/tests/set.test.ts +142 -0
- package/node_modules/zod/src/v3/tests/standard-schema.test.ts +83 -0
- package/node_modules/zod/src/v3/tests/string.test.ts +916 -0
- package/node_modules/zod/src/v3/tests/transformer.test.ts +233 -0
- package/node_modules/zod/src/v3/tests/tuple.test.ts +90 -0
- package/node_modules/zod/src/v3/tests/unions.test.ts +57 -0
- package/node_modules/zod/src/v3/tests/validations.test.ts +133 -0
- package/node_modules/zod/src/v3/tests/void.test.ts +15 -0
- package/node_modules/zod/src/v3/types.ts +5136 -0
- package/node_modules/zod/src/v4/classic/checks.ts +30 -0
- package/node_modules/zod/src/v4/classic/coerce.ts +27 -0
- package/node_modules/zod/src/v4/classic/compat.ts +66 -0
- package/node_modules/zod/src/v4/classic/errors.ts +75 -0
- package/node_modules/zod/src/v4/classic/external.ts +50 -0
- package/node_modules/zod/src/v4/classic/index.ts +5 -0
- package/node_modules/zod/src/v4/classic/iso.ts +90 -0
- package/node_modules/zod/src/v4/classic/parse.ts +33 -0
- package/node_modules/zod/src/v4/classic/schemas.ts +2054 -0
- package/node_modules/zod/src/v4/classic/tests/anyunknown.test.ts +26 -0
- package/node_modules/zod/src/v4/classic/tests/array.test.ts +264 -0
- package/node_modules/zod/src/v4/classic/tests/assignability.test.ts +210 -0
- package/node_modules/zod/src/v4/classic/tests/async-parsing.test.ts +381 -0
- package/node_modules/zod/src/v4/classic/tests/async-refinements.test.ts +68 -0
- package/node_modules/zod/src/v4/classic/tests/base.test.ts +7 -0
- package/node_modules/zod/src/v4/classic/tests/bigint.test.ts +54 -0
- package/node_modules/zod/src/v4/classic/tests/brand.test.ts +63 -0
- package/node_modules/zod/src/v4/classic/tests/catch.test.ts +252 -0
- package/node_modules/zod/src/v4/classic/tests/coalesce.test.ts +20 -0
- package/node_modules/zod/src/v4/classic/tests/coerce.test.ts +160 -0
- package/node_modules/zod/src/v4/classic/tests/continuability.test.ts +352 -0
- package/node_modules/zod/src/v4/classic/tests/custom.test.ts +40 -0
- package/node_modules/zod/src/v4/classic/tests/date.test.ts +31 -0
- package/node_modules/zod/src/v4/classic/tests/datetime.test.ts +296 -0
- package/node_modules/zod/src/v4/classic/tests/default.test.ts +313 -0
- package/node_modules/zod/src/v4/classic/tests/description.test.ts +32 -0
- package/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts +619 -0
- package/node_modules/zod/src/v4/classic/tests/enum.test.ts +285 -0
- package/node_modules/zod/src/v4/classic/tests/error-utils.test.ts +527 -0
- package/node_modules/zod/src/v4/classic/tests/error.test.ts +711 -0
- package/node_modules/zod/src/v4/classic/tests/file.test.ts +91 -0
- package/node_modules/zod/src/v4/classic/tests/firstparty.test.ts +175 -0
- package/node_modules/zod/src/v4/classic/tests/function.test.ts +268 -0
- package/node_modules/zod/src/v4/classic/tests/generics.test.ts +72 -0
- package/node_modules/zod/src/v4/classic/tests/index.test.ts +829 -0
- package/node_modules/zod/src/v4/classic/tests/instanceof.test.ts +34 -0
- package/node_modules/zod/src/v4/classic/tests/intersection.test.ts +171 -0
- package/node_modules/zod/src/v4/classic/tests/json.test.ts +108 -0
- package/node_modules/zod/src/v4/classic/tests/lazy.test.ts +227 -0
- package/node_modules/zod/src/v4/classic/tests/literal.test.ts +92 -0
- package/node_modules/zod/src/v4/classic/tests/map.test.ts +196 -0
- package/node_modules/zod/src/v4/classic/tests/nan.test.ts +21 -0
- package/node_modules/zod/src/v4/classic/tests/nested-refine.test.ts +168 -0
- package/node_modules/zod/src/v4/classic/tests/nonoptional.test.ts +86 -0
- package/node_modules/zod/src/v4/classic/tests/nullable.test.ts +22 -0
- package/node_modules/zod/src/v4/classic/tests/number.test.ts +247 -0
- package/node_modules/zod/src/v4/classic/tests/object.test.ts +563 -0
- package/node_modules/zod/src/v4/classic/tests/optional.test.ts +123 -0
- package/node_modules/zod/src/v4/classic/tests/partial.test.ts +147 -0
- package/node_modules/zod/src/v4/classic/tests/pickomit.test.ts +127 -0
- package/node_modules/zod/src/v4/classic/tests/pipe.test.ts +81 -0
- package/node_modules/zod/src/v4/classic/tests/prefault.test.ts +37 -0
- package/node_modules/zod/src/v4/classic/tests/preprocess.test.ts +298 -0
- package/node_modules/zod/src/v4/classic/tests/primitive.test.ts +175 -0
- package/node_modules/zod/src/v4/classic/tests/promise.test.ts +81 -0
- package/node_modules/zod/src/v4/classic/tests/prototypes.test.ts +23 -0
- package/node_modules/zod/src/v4/classic/tests/readonly.test.ts +252 -0
- package/node_modules/zod/src/v4/classic/tests/record.test.ts +342 -0
- package/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts +356 -0
- package/node_modules/zod/src/v4/classic/tests/refine.test.ts +532 -0
- package/node_modules/zod/src/v4/classic/tests/registries.test.ts +204 -0
- package/node_modules/zod/src/v4/classic/tests/set.test.ts +179 -0
- package/node_modules/zod/src/v4/classic/tests/standard-schema.test.ts +57 -0
- package/node_modules/zod/src/v4/classic/tests/string-formats.test.ts +109 -0
- package/node_modules/zod/src/v4/classic/tests/string.test.ts +881 -0
- package/node_modules/zod/src/v4/classic/tests/stringbool.test.ts +66 -0
- package/node_modules/zod/src/v4/classic/tests/template-literal.test.ts +758 -0
- package/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts +2314 -0
- package/node_modules/zod/src/v4/classic/tests/transform.test.ts +250 -0
- package/node_modules/zod/src/v4/classic/tests/tuple.test.ts +163 -0
- package/node_modules/zod/src/v4/classic/tests/union.test.ts +94 -0
- package/node_modules/zod/src/v4/classic/tests/validations.test.ts +283 -0
- package/node_modules/zod/src/v4/classic/tests/void.test.ts +12 -0
- package/node_modules/zod/src/v4/core/api.ts +1594 -0
- package/node_modules/zod/src/v4/core/checks.ts +1283 -0
- package/node_modules/zod/src/v4/core/config.ts +15 -0
- package/node_modules/zod/src/v4/core/core.ts +134 -0
- package/node_modules/zod/src/v4/core/doc.ts +44 -0
- package/node_modules/zod/src/v4/core/errors.ts +424 -0
- package/node_modules/zod/src/v4/core/function.ts +176 -0
- package/node_modules/zod/src/v4/core/index.ts +15 -0
- package/node_modules/zod/src/v4/core/json-schema.ts +143 -0
- package/node_modules/zod/src/v4/core/parse.ts +94 -0
- package/node_modules/zod/src/v4/core/regexes.ts +135 -0
- package/node_modules/zod/src/v4/core/registries.ts +96 -0
- package/node_modules/zod/src/v4/core/schemas.ts +3842 -0
- package/node_modules/zod/src/v4/core/standard-schema.ts +64 -0
- package/node_modules/zod/src/v4/core/tests/index.test.ts +46 -0
- package/node_modules/zod/src/v4/core/tests/locales/be.test.ts +124 -0
- package/node_modules/zod/src/v4/core/tests/locales/en.test.ts +22 -0
- package/node_modules/zod/src/v4/core/tests/locales/ru.test.ts +128 -0
- package/node_modules/zod/src/v4/core/tests/locales/tr.test.ts +69 -0
- package/node_modules/zod/src/v4/core/to-json-schema.ts +977 -0
- package/node_modules/zod/src/v4/core/util.ts +775 -0
- package/node_modules/zod/src/v4/core/versions.ts +5 -0
- package/node_modules/zod/src/v4/core/zsf.ts +323 -0
- package/node_modules/zod/src/v4/index.ts +4 -0
- package/node_modules/zod/src/v4/locales/ar.ts +125 -0
- package/node_modules/zod/src/v4/locales/az.ts +121 -0
- package/node_modules/zod/src/v4/locales/be.ts +184 -0
- package/node_modules/zod/src/v4/locales/ca.ts +127 -0
- package/node_modules/zod/src/v4/locales/cs.ts +142 -0
- package/node_modules/zod/src/v4/locales/de.ts +124 -0
- package/node_modules/zod/src/v4/locales/en.ts +127 -0
- package/node_modules/zod/src/v4/locales/eo.ts +125 -0
- package/node_modules/zod/src/v4/locales/es.ts +125 -0
- package/node_modules/zod/src/v4/locales/fa.ts +134 -0
- package/node_modules/zod/src/v4/locales/fi.ts +131 -0
- package/node_modules/zod/src/v4/locales/fr-CA.ts +126 -0
- package/node_modules/zod/src/v4/locales/fr.ts +124 -0
- package/node_modules/zod/src/v4/locales/he.ts +125 -0
- package/node_modules/zod/src/v4/locales/hu.ts +126 -0
- package/node_modules/zod/src/v4/locales/id.ts +125 -0
- package/node_modules/zod/src/v4/locales/index.ts +39 -0
- package/node_modules/zod/src/v4/locales/it.ts +125 -0
- package/node_modules/zod/src/v4/locales/ja.ts +122 -0
- package/node_modules/zod/src/v4/locales/kh.ts +126 -0
- package/node_modules/zod/src/v4/locales/ko.ts +131 -0
- package/node_modules/zod/src/v4/locales/mk.ts +127 -0
- package/node_modules/zod/src/v4/locales/ms.ts +124 -0
- package/node_modules/zod/src/v4/locales/nl.ts +126 -0
- package/node_modules/zod/src/v4/locales/no.ts +124 -0
- package/node_modules/zod/src/v4/locales/ota.ts +125 -0
- package/node_modules/zod/src/v4/locales/pl.ts +126 -0
- package/node_modules/zod/src/v4/locales/ps.ts +133 -0
- package/node_modules/zod/src/v4/locales/pt.ts +123 -0
- package/node_modules/zod/src/v4/locales/ru.ts +184 -0
- package/node_modules/zod/src/v4/locales/sl.ts +126 -0
- package/node_modules/zod/src/v4/locales/sv.ts +127 -0
- package/node_modules/zod/src/v4/locales/ta.ts +125 -0
- package/node_modules/zod/src/v4/locales/th.ts +126 -0
- package/node_modules/zod/src/v4/locales/tr.ts +121 -0
- package/node_modules/zod/src/v4/locales/ua.ts +126 -0
- package/node_modules/zod/src/v4/locales/ur.ts +126 -0
- package/node_modules/zod/src/v4/locales/vi.ts +125 -0
- package/node_modules/zod/src/v4/locales/zh-CN.ts +123 -0
- package/node_modules/zod/src/v4/locales/zh-TW.ts +125 -0
- package/node_modules/zod/src/v4/mini/checks.ts +32 -0
- package/node_modules/zod/src/v4/mini/coerce.ts +22 -0
- package/node_modules/zod/src/v4/mini/external.ts +40 -0
- package/node_modules/zod/src/v4/mini/index.ts +3 -0
- package/node_modules/zod/src/v4/mini/iso.ts +62 -0
- package/node_modules/zod/src/v4/mini/parse.ts +1 -0
- package/node_modules/zod/src/v4/mini/schemas.ts +1579 -0
- package/node_modules/zod/src/v4/mini/tests/assignability.test.ts +129 -0
- package/node_modules/zod/src/v4/mini/tests/brand.test.ts +51 -0
- package/node_modules/zod/src/v4/mini/tests/checks.test.ts +144 -0
- package/node_modules/zod/src/v4/mini/tests/computed.test.ts +36 -0
- package/node_modules/zod/src/v4/mini/tests/error.test.ts +22 -0
- package/node_modules/zod/src/v4/mini/tests/functions.test.ts +43 -0
- package/node_modules/zod/src/v4/mini/tests/index.test.ts +871 -0
- package/node_modules/zod/src/v4/mini/tests/number.test.ts +95 -0
- package/node_modules/zod/src/v4/mini/tests/object.test.ts +185 -0
- package/node_modules/zod/src/v4/mini/tests/prototypes.test.ts +43 -0
- package/node_modules/zod/src/v4/mini/tests/recursive-types.test.ts +275 -0
- package/node_modules/zod/src/v4/mini/tests/string.test.ts +299 -0
- package/node_modules/zod/src/v4-mini/index.ts +1 -0
- package/node_modules/zod/v3/ZodError.cjs +138 -0
- package/node_modules/zod/v3/ZodError.d.cts +164 -0
- package/node_modules/zod/v3/ZodError.d.ts +164 -0
- package/node_modules/zod/v3/ZodError.js +133 -0
- package/node_modules/zod/v3/errors.cjs +17 -0
- package/node_modules/zod/v3/errors.d.cts +5 -0
- package/node_modules/zod/v3/errors.d.ts +5 -0
- package/node_modules/zod/v3/errors.js +9 -0
- package/node_modules/zod/v3/external.cjs +22 -0
- package/node_modules/zod/v3/external.d.cts +6 -0
- package/node_modules/zod/v3/external.d.ts +6 -0
- package/node_modules/zod/v3/external.js +6 -0
- package/node_modules/zod/v3/helpers/enumUtil.cjs +2 -0
- package/node_modules/zod/v3/helpers/enumUtil.d.cts +8 -0
- package/node_modules/zod/v3/helpers/enumUtil.d.ts +8 -0
- package/node_modules/zod/v3/helpers/enumUtil.js +1 -0
- package/node_modules/zod/v3/helpers/errorUtil.cjs +9 -0
- package/node_modules/zod/v3/helpers/errorUtil.d.cts +9 -0
- package/node_modules/zod/v3/helpers/errorUtil.d.ts +9 -0
- package/node_modules/zod/v3/helpers/errorUtil.js +6 -0
- package/node_modules/zod/v3/helpers/parseUtil.cjs +124 -0
- package/node_modules/zod/v3/helpers/parseUtil.d.cts +78 -0
- package/node_modules/zod/v3/helpers/parseUtil.d.ts +78 -0
- package/node_modules/zod/v3/helpers/parseUtil.js +109 -0
- package/node_modules/zod/v3/helpers/partialUtil.cjs +2 -0
- package/node_modules/zod/v3/helpers/partialUtil.d.cts +8 -0
- package/node_modules/zod/v3/helpers/partialUtil.d.ts +8 -0
- package/node_modules/zod/v3/helpers/partialUtil.js +1 -0
- package/node_modules/zod/v3/helpers/typeAliases.cjs +2 -0
- package/node_modules/zod/v3/helpers/typeAliases.d.cts +2 -0
- package/node_modules/zod/v3/helpers/typeAliases.d.ts +2 -0
- package/node_modules/zod/v3/helpers/typeAliases.js +1 -0
- package/node_modules/zod/v3/helpers/util.cjs +137 -0
- package/node_modules/zod/v3/helpers/util.d.cts +85 -0
- package/node_modules/zod/v3/helpers/util.d.ts +85 -0
- package/node_modules/zod/v3/helpers/util.js +133 -0
- package/node_modules/zod/v3/index.cjs +33 -0
- package/node_modules/zod/v3/index.d.cts +4 -0
- package/node_modules/zod/v3/index.d.ts +4 -0
- package/node_modules/zod/v3/index.js +4 -0
- package/node_modules/zod/v3/locales/en.cjs +111 -0
- package/node_modules/zod/v3/locales/en.d.cts +3 -0
- package/node_modules/zod/v3/locales/en.d.ts +3 -0
- package/node_modules/zod/v3/locales/en.js +109 -0
- package/node_modules/zod/v3/standard-schema.cjs +2 -0
- package/node_modules/zod/v3/standard-schema.d.cts +102 -0
- package/node_modules/zod/v3/standard-schema.d.ts +102 -0
- package/node_modules/zod/v3/standard-schema.js +1 -0
- package/node_modules/zod/v3/types.cjs +3775 -0
- package/node_modules/zod/v3/types.d.cts +1031 -0
- package/node_modules/zod/v3/types.d.ts +1031 -0
- package/node_modules/zod/v3/types.js +3693 -0
- package/node_modules/zod/v4/classic/checks.cjs +32 -0
- package/node_modules/zod/v4/classic/checks.d.cts +1 -0
- package/node_modules/zod/v4/classic/checks.d.ts +1 -0
- package/node_modules/zod/v4/classic/checks.js +1 -0
- package/node_modules/zod/v4/classic/coerce.cjs +47 -0
- package/node_modules/zod/v4/classic/coerce.d.cts +17 -0
- package/node_modules/zod/v4/classic/coerce.d.ts +17 -0
- package/node_modules/zod/v4/classic/coerce.js +17 -0
- package/node_modules/zod/v4/classic/compat.cjs +57 -0
- package/node_modules/zod/v4/classic/compat.d.cts +46 -0
- package/node_modules/zod/v4/classic/compat.d.ts +46 -0
- package/node_modules/zod/v4/classic/compat.js +27 -0
- package/node_modules/zod/v4/classic/errors.cjs +67 -0
- package/node_modules/zod/v4/classic/errors.d.cts +30 -0
- package/node_modules/zod/v4/classic/errors.d.ts +30 -0
- package/node_modules/zod/v4/classic/errors.js +41 -0
- package/node_modules/zod/v4/classic/external.cjs +70 -0
- package/node_modules/zod/v4/classic/external.d.cts +13 -0
- package/node_modules/zod/v4/classic/external.d.ts +13 -0
- package/node_modules/zod/v4/classic/external.js +18 -0
- package/node_modules/zod/v4/classic/index.cjs +33 -0
- package/node_modules/zod/v4/classic/index.d.cts +4 -0
- package/node_modules/zod/v4/classic/index.d.ts +4 -0
- package/node_modules/zod/v4/classic/index.js +4 -0
- package/node_modules/zod/v4/classic/iso.cjs +60 -0
- package/node_modules/zod/v4/classic/iso.d.cts +22 -0
- package/node_modules/zod/v4/classic/iso.d.ts +22 -0
- package/node_modules/zod/v4/classic/iso.js +30 -0
- package/node_modules/zod/v4/classic/parse.cjs +32 -0
- package/node_modules/zod/v4/classic/parse.d.cts +23 -0
- package/node_modules/zod/v4/classic/parse.d.ts +23 -0
- package/node_modules/zod/v4/classic/parse.js +6 -0
- package/node_modules/zod/v4/classic/schemas.cjs +1109 -0
- package/node_modules/zod/v4/classic/schemas.d.cts +630 -0
- package/node_modules/zod/v4/classic/schemas.d.ts +630 -0
- package/node_modules/zod/v4/classic/schemas.js +1006 -0
- package/node_modules/zod/v4/core/api.cjs +1039 -0
- package/node_modules/zod/v4/core/api.d.cts +284 -0
- package/node_modules/zod/v4/core/api.d.ts +284 -0
- package/node_modules/zod/v4/core/api.js +906 -0
- package/node_modules/zod/v4/core/checks.cjs +591 -0
- package/node_modules/zod/v4/core/checks.d.cts +278 -0
- package/node_modules/zod/v4/core/checks.d.ts +278 -0
- package/node_modules/zod/v4/core/checks.js +565 -0
- package/node_modules/zod/v4/core/core.cjs +67 -0
- package/node_modules/zod/v4/core/core.d.cts +49 -0
- package/node_modules/zod/v4/core/core.d.ts +49 -0
- package/node_modules/zod/v4/core/core.js +61 -0
- package/node_modules/zod/v4/core/doc.cjs +39 -0
- package/node_modules/zod/v4/core/doc.d.cts +14 -0
- package/node_modules/zod/v4/core/doc.d.ts +14 -0
- package/node_modules/zod/v4/core/doc.js +35 -0
- package/node_modules/zod/v4/core/errors.cjs +226 -0
- package/node_modules/zod/v4/core/errors.d.cts +208 -0
- package/node_modules/zod/v4/core/errors.d.ts +208 -0
- package/node_modules/zod/v4/core/errors.js +195 -0
- package/node_modules/zod/v4/core/function.cjs +102 -0
- package/node_modules/zod/v4/core/function.d.cts +52 -0
- package/node_modules/zod/v4/core/function.d.ts +52 -0
- package/node_modules/zod/v4/core/function.js +75 -0
- package/node_modules/zod/v4/core/index.cjs +44 -0
- package/node_modules/zod/v4/core/index.d.cts +15 -0
- package/node_modules/zod/v4/core/index.d.ts +15 -0
- package/node_modules/zod/v4/core/index.js +15 -0
- package/node_modules/zod/v4/core/json-schema.cjs +2 -0
- package/node_modules/zod/v4/core/json-schema.d.cts +87 -0
- package/node_modules/zod/v4/core/json-schema.d.ts +87 -0
- package/node_modules/zod/v4/core/json-schema.js +1 -0
- package/node_modules/zod/v4/core/parse.cjs +87 -0
- package/node_modules/zod/v4/core/parse.d.cts +25 -0
- package/node_modules/zod/v4/core/parse.d.ts +25 -0
- package/node_modules/zod/v4/core/parse.js +57 -0
- package/node_modules/zod/v4/core/regexes.cjs +103 -0
- package/node_modules/zod/v4/core/regexes.d.cts +62 -0
- package/node_modules/zod/v4/core/regexes.d.ts +62 -0
- package/node_modules/zod/v4/core/regexes.js +95 -0
- package/node_modules/zod/v4/core/registries.cjs +56 -0
- package/node_modules/zod/v4/core/registries.d.cts +35 -0
- package/node_modules/zod/v4/core/registries.d.ts +35 -0
- package/node_modules/zod/v4/core/registries.js +51 -0
- package/node_modules/zod/v4/core/schemas.cjs +1748 -0
- package/node_modules/zod/v4/core/schemas.d.cts +1041 -0
- package/node_modules/zod/v4/core/schemas.d.ts +1041 -0
- package/node_modules/zod/v4/core/schemas.js +1717 -0
- package/node_modules/zod/v4/core/standard-schema.cjs +2 -0
- package/node_modules/zod/v4/core/standard-schema.d.cts +55 -0
- package/node_modules/zod/v4/core/standard-schema.d.ts +55 -0
- package/node_modules/zod/v4/core/standard-schema.js +1 -0
- package/node_modules/zod/v4/core/to-json-schema.cjs +854 -0
- package/node_modules/zod/v4/core/to-json-schema.d.cts +88 -0
- package/node_modules/zod/v4/core/to-json-schema.d.ts +88 -0
- package/node_modules/zod/v4/core/to-json-schema.js +849 -0
- package/node_modules/zod/v4/core/util.cjs +539 -0
- package/node_modules/zod/v4/core/util.d.cts +183 -0
- package/node_modules/zod/v4/core/util.d.ts +183 -0
- package/node_modules/zod/v4/core/util.js +493 -0
- package/node_modules/zod/v4/core/versions.cjs +8 -0
- package/node_modules/zod/v4/core/versions.d.cts +5 -0
- package/node_modules/zod/v4/core/versions.d.ts +5 -0
- package/node_modules/zod/v4/core/versions.js +5 -0
- package/node_modules/zod/v4/index.cjs +22 -0
- package/node_modules/zod/v4/index.d.cts +3 -0
- package/node_modules/zod/v4/index.d.ts +3 -0
- package/node_modules/zod/v4/index.js +3 -0
- package/node_modules/zod/v4/locales/ar.cjs +142 -0
- package/node_modules/zod/v4/locales/ar.d.cts +4 -0
- package/node_modules/zod/v4/locales/ar.d.ts +4 -0
- package/node_modules/zod/v4/locales/ar.js +116 -0
- package/node_modules/zod/v4/locales/az.cjs +141 -0
- package/node_modules/zod/v4/locales/az.d.cts +4 -0
- package/node_modules/zod/v4/locales/az.d.ts +4 -0
- package/node_modules/zod/v4/locales/az.js +115 -0
- package/node_modules/zod/v4/locales/be.cjs +190 -0
- package/node_modules/zod/v4/locales/be.d.cts +4 -0
- package/node_modules/zod/v4/locales/be.d.ts +4 -0
- package/node_modules/zod/v4/locales/be.js +164 -0
- package/node_modules/zod/v4/locales/ca.cjs +144 -0
- package/node_modules/zod/v4/locales/ca.d.cts +4 -0
- package/node_modules/zod/v4/locales/ca.d.ts +4 -0
- package/node_modules/zod/v4/locales/ca.js +118 -0
- package/node_modules/zod/v4/locales/cs.cjs +161 -0
- package/node_modules/zod/v4/locales/cs.d.cts +4 -0
- package/node_modules/zod/v4/locales/cs.d.ts +4 -0
- package/node_modules/zod/v4/locales/cs.js +135 -0
- package/node_modules/zod/v4/locales/de.cjs +142 -0
- package/node_modules/zod/v4/locales/de.d.cts +4 -0
- package/node_modules/zod/v4/locales/de.d.ts +4 -0
- package/node_modules/zod/v4/locales/de.js +116 -0
- package/node_modules/zod/v4/locales/en.cjs +145 -0
- package/node_modules/zod/v4/locales/en.d.cts +5 -0
- package/node_modules/zod/v4/locales/en.d.ts +5 -0
- package/node_modules/zod/v4/locales/en.js +117 -0
- package/node_modules/zod/v4/locales/eo.cjs +144 -0
- package/node_modules/zod/v4/locales/eo.d.cts +5 -0
- package/node_modules/zod/v4/locales/eo.d.ts +5 -0
- package/node_modules/zod/v4/locales/eo.js +116 -0
- package/node_modules/zod/v4/locales/es.cjs +143 -0
- package/node_modules/zod/v4/locales/es.d.cts +4 -0
- package/node_modules/zod/v4/locales/es.d.ts +4 -0
- package/node_modules/zod/v4/locales/es.js +117 -0
- package/node_modules/zod/v4/locales/fa.cjs +148 -0
- package/node_modules/zod/v4/locales/fa.d.cts +4 -0
- package/node_modules/zod/v4/locales/fa.d.ts +4 -0
- package/node_modules/zod/v4/locales/fa.js +122 -0
- package/node_modules/zod/v4/locales/fi.cjs +148 -0
- package/node_modules/zod/v4/locales/fi.d.cts +4 -0
- package/node_modules/zod/v4/locales/fi.d.ts +4 -0
- package/node_modules/zod/v4/locales/fi.js +122 -0
- package/node_modules/zod/v4/locales/fr-CA.cjs +143 -0
- package/node_modules/zod/v4/locales/fr-CA.d.cts +4 -0
- package/node_modules/zod/v4/locales/fr-CA.d.ts +4 -0
- package/node_modules/zod/v4/locales/fr-CA.js +117 -0
- package/node_modules/zod/v4/locales/fr.cjs +142 -0
- package/node_modules/zod/v4/locales/fr.d.cts +4 -0
- package/node_modules/zod/v4/locales/fr.d.ts +4 -0
- package/node_modules/zod/v4/locales/fr.js +116 -0
- package/node_modules/zod/v4/locales/he.cjs +143 -0
- package/node_modules/zod/v4/locales/he.d.cts +4 -0
- package/node_modules/zod/v4/locales/he.d.ts +4 -0
- package/node_modules/zod/v4/locales/he.js +117 -0
- package/node_modules/zod/v4/locales/hu.cjs +143 -0
- package/node_modules/zod/v4/locales/hu.d.cts +4 -0
- package/node_modules/zod/v4/locales/hu.d.ts +4 -0
- package/node_modules/zod/v4/locales/hu.js +117 -0
- package/node_modules/zod/v4/locales/id.cjs +142 -0
- package/node_modules/zod/v4/locales/id.d.cts +4 -0
- package/node_modules/zod/v4/locales/id.d.ts +4 -0
- package/node_modules/zod/v4/locales/id.js +116 -0
- package/node_modules/zod/v4/locales/index.cjs +84 -0
- package/node_modules/zod/v4/locales/index.d.cts +39 -0
- package/node_modules/zod/v4/locales/index.d.ts +39 -0
- package/node_modules/zod/v4/locales/index.js +39 -0
- package/node_modules/zod/v4/locales/it.cjs +143 -0
- package/node_modules/zod/v4/locales/it.d.cts +4 -0
- package/node_modules/zod/v4/locales/it.d.ts +4 -0
- package/node_modules/zod/v4/locales/it.js +117 -0
- package/node_modules/zod/v4/locales/ja.cjs +141 -0
- package/node_modules/zod/v4/locales/ja.d.cts +4 -0
- package/node_modules/zod/v4/locales/ja.d.ts +4 -0
- package/node_modules/zod/v4/locales/ja.js +115 -0
- package/node_modules/zod/v4/locales/kh.cjs +143 -0
- package/node_modules/zod/v4/locales/kh.d.cts +4 -0
- package/node_modules/zod/v4/locales/kh.d.ts +4 -0
- package/node_modules/zod/v4/locales/kh.js +117 -0
- package/node_modules/zod/v4/locales/ko.cjs +147 -0
- package/node_modules/zod/v4/locales/ko.d.cts +4 -0
- package/node_modules/zod/v4/locales/ko.d.ts +4 -0
- package/node_modules/zod/v4/locales/ko.js +121 -0
- package/node_modules/zod/v4/locales/mk.cjs +144 -0
- package/node_modules/zod/v4/locales/mk.d.cts +4 -0
- package/node_modules/zod/v4/locales/mk.d.ts +4 -0
- package/node_modules/zod/v4/locales/mk.js +118 -0
- package/node_modules/zod/v4/locales/ms.cjs +142 -0
- package/node_modules/zod/v4/locales/ms.d.cts +4 -0
- package/node_modules/zod/v4/locales/ms.d.ts +4 -0
- package/node_modules/zod/v4/locales/ms.js +116 -0
- package/node_modules/zod/v4/locales/nl.cjs +143 -0
- package/node_modules/zod/v4/locales/nl.d.cts +4 -0
- package/node_modules/zod/v4/locales/nl.d.ts +4 -0
- package/node_modules/zod/v4/locales/nl.js +117 -0
- package/node_modules/zod/v4/locales/no.cjs +142 -0
- package/node_modules/zod/v4/locales/no.d.cts +4 -0
- package/node_modules/zod/v4/locales/no.d.ts +4 -0
- package/node_modules/zod/v4/locales/no.js +116 -0
- package/node_modules/zod/v4/locales/ota.cjs +143 -0
- package/node_modules/zod/v4/locales/ota.d.cts +4 -0
- package/node_modules/zod/v4/locales/ota.d.ts +4 -0
- package/node_modules/zod/v4/locales/ota.js +117 -0
- package/node_modules/zod/v4/locales/pl.cjs +143 -0
- package/node_modules/zod/v4/locales/pl.d.cts +4 -0
- package/node_modules/zod/v4/locales/pl.d.ts +4 -0
- package/node_modules/zod/v4/locales/pl.js +117 -0
- package/node_modules/zod/v4/locales/ps.cjs +148 -0
- package/node_modules/zod/v4/locales/ps.d.cts +4 -0
- package/node_modules/zod/v4/locales/ps.d.ts +4 -0
- package/node_modules/zod/v4/locales/ps.js +122 -0
- package/node_modules/zod/v4/locales/pt.cjs +142 -0
- package/node_modules/zod/v4/locales/pt.d.cts +4 -0
- package/node_modules/zod/v4/locales/pt.d.ts +4 -0
- package/node_modules/zod/v4/locales/pt.js +116 -0
- package/node_modules/zod/v4/locales/ru.cjs +190 -0
- package/node_modules/zod/v4/locales/ru.d.cts +4 -0
- package/node_modules/zod/v4/locales/ru.d.ts +4 -0
- package/node_modules/zod/v4/locales/ru.js +164 -0
- package/node_modules/zod/v4/locales/sl.cjs +143 -0
- package/node_modules/zod/v4/locales/sl.d.cts +4 -0
- package/node_modules/zod/v4/locales/sl.d.ts +4 -0
- package/node_modules/zod/v4/locales/sl.js +117 -0
- package/node_modules/zod/v4/locales/sv.cjs +144 -0
- package/node_modules/zod/v4/locales/sv.d.cts +4 -0
- package/node_modules/zod/v4/locales/sv.d.ts +4 -0
- package/node_modules/zod/v4/locales/sv.js +118 -0
- package/node_modules/zod/v4/locales/ta.cjs +143 -0
- package/node_modules/zod/v4/locales/ta.d.cts +4 -0
- package/node_modules/zod/v4/locales/ta.d.ts +4 -0
- package/node_modules/zod/v4/locales/ta.js +117 -0
- package/node_modules/zod/v4/locales/th.cjs +143 -0
- package/node_modules/zod/v4/locales/th.d.cts +4 -0
- package/node_modules/zod/v4/locales/th.d.ts +4 -0
- package/node_modules/zod/v4/locales/th.js +117 -0
- package/node_modules/zod/v4/locales/tr.cjs +143 -0
- package/node_modules/zod/v4/locales/tr.d.cts +5 -0
- package/node_modules/zod/v4/locales/tr.d.ts +5 -0
- package/node_modules/zod/v4/locales/tr.js +115 -0
- package/node_modules/zod/v4/locales/ua.cjs +143 -0
- package/node_modules/zod/v4/locales/ua.d.cts +4 -0
- package/node_modules/zod/v4/locales/ua.d.ts +4 -0
- package/node_modules/zod/v4/locales/ua.js +117 -0
- package/node_modules/zod/v4/locales/ur.cjs +143 -0
- package/node_modules/zod/v4/locales/ur.d.cts +4 -0
- package/node_modules/zod/v4/locales/ur.d.ts +4 -0
- package/node_modules/zod/v4/locales/ur.js +117 -0
- package/node_modules/zod/v4/locales/vi.cjs +142 -0
- package/node_modules/zod/v4/locales/vi.d.cts +4 -0
- package/node_modules/zod/v4/locales/vi.d.ts +4 -0
- package/node_modules/zod/v4/locales/vi.js +116 -0
- package/node_modules/zod/v4/locales/zh-CN.cjs +142 -0
- package/node_modules/zod/v4/locales/zh-CN.d.cts +4 -0
- package/node_modules/zod/v4/locales/zh-CN.d.ts +4 -0
- package/node_modules/zod/v4/locales/zh-CN.js +116 -0
- package/node_modules/zod/v4/locales/zh-TW.cjs +143 -0
- package/node_modules/zod/v4/locales/zh-TW.d.cts +4 -0
- package/node_modules/zod/v4/locales/zh-TW.d.ts +4 -0
- package/node_modules/zod/v4/locales/zh-TW.js +117 -0
- package/node_modules/zod/v4/mini/checks.cjs +34 -0
- package/node_modules/zod/v4/mini/checks.d.cts +1 -0
- package/node_modules/zod/v4/mini/checks.d.ts +1 -0
- package/node_modules/zod/v4/mini/checks.js +1 -0
- package/node_modules/zod/v4/mini/coerce.cjs +47 -0
- package/node_modules/zod/v4/mini/coerce.d.cts +7 -0
- package/node_modules/zod/v4/mini/coerce.d.ts +7 -0
- package/node_modules/zod/v4/mini/coerce.js +17 -0
- package/node_modules/zod/v4/mini/external.cjs +62 -0
- package/node_modules/zod/v4/mini/external.d.cts +11 -0
- package/node_modules/zod/v4/mini/external.d.ts +11 -0
- package/node_modules/zod/v4/mini/external.js +13 -0
- package/node_modules/zod/v4/mini/index.cjs +32 -0
- package/node_modules/zod/v4/mini/index.d.cts +3 -0
- package/node_modules/zod/v4/mini/index.d.ts +3 -0
- package/node_modules/zod/v4/mini/index.js +3 -0
- package/node_modules/zod/v4/mini/iso.cjs +60 -0
- package/node_modules/zod/v4/mini/iso.d.cts +22 -0
- package/node_modules/zod/v4/mini/iso.d.ts +22 -0
- package/node_modules/zod/v4/mini/iso.js +30 -0
- package/node_modules/zod/v4/mini/parse.cjs +8 -0
- package/node_modules/zod/v4/mini/parse.d.cts +1 -0
- package/node_modules/zod/v4/mini/parse.d.ts +1 -0
- package/node_modules/zod/v4/mini/parse.js +1 -0
- package/node_modules/zod/v4/mini/schemas.cjs +839 -0
- package/node_modules/zod/v4/mini/schemas.d.cts +356 -0
- package/node_modules/zod/v4/mini/schemas.d.ts +356 -0
- package/node_modules/zod/v4/mini/schemas.js +732 -0
- package/node_modules/zod/v4-mini/index.cjs +17 -0
- package/node_modules/zod/v4-mini/index.d.cts +1 -0
- package/node_modules/zod/v4-mini/index.d.ts +1 -0
- package/node_modules/zod/v4-mini/index.js +1 -0
- package/package.json +97 -0
|
@@ -0,0 +1,1195 @@
|
|
|
1
|
+
import { quote } from '../utils/shell-quote.js';
|
|
2
|
+
import { spawn } from 'child_process';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { logForDebugging } from '../utils/debug.js';
|
|
5
|
+
import { whichSync } from '../utils/which.js';
|
|
6
|
+
import { buildJavaToolOptions } from './java-proxy-agent.js';
|
|
7
|
+
import { normalizePathForSandbox, generateProxyEnvVars, buildPosixGitSafeDirEnv, attributionKeyFor, encodeSandboxedCommand, decodeSandboxedCommand, containsGlobChars, globToRegex, denyGlobRegex, isStrictlyUnder as isPathStrictlyUnder, DANGEROUS_FILES, getDangerousDirectories, } from './sandbox-utils.js';
|
|
8
|
+
import { shouldIgnoreViolation } from './sandbox-violation-store.js';
|
|
9
|
+
/**
|
|
10
|
+
* The mandatory write denies (no filesystem scanning). Each name appears
|
|
11
|
+
* twice: once as the path in the cwd, and once as a pattern for the same
|
|
12
|
+
* name anywhere beneath it, which macOS matches via a regex.
|
|
13
|
+
*
|
|
14
|
+
* Both are anchored at the cwd, and the cwd is a name on disk that may
|
|
15
|
+
* contain `[`, `*` or `?`. So the first is a literal entry, and the second
|
|
16
|
+
* carries the cwd as its anchor — only the `**\/<name>` tail is pattern.
|
|
17
|
+
* Compiled as one glob, a cwd like `a[b/c]d` would turn into a character
|
|
18
|
+
* class and every one of these denies would match nothing.
|
|
19
|
+
*/
|
|
20
|
+
export function macGetMandatoryDenyEntries(allowGitConfig = false) {
|
|
21
|
+
const cwd = normalizePathForSandbox(process.cwd(), { literal: true });
|
|
22
|
+
const entries = [];
|
|
23
|
+
const literal = (relativePath) => toLiteralPathEntry(path.resolve(cwd, relativePath));
|
|
24
|
+
const beneathCwd = (pattern) => anchoredGlobEntry(cwd, pattern);
|
|
25
|
+
// Dangerous files - static paths in CWD + glob patterns for subtree
|
|
26
|
+
for (const fileName of DANGEROUS_FILES) {
|
|
27
|
+
entries.push(literal(fileName));
|
|
28
|
+
entries.push(beneathCwd(`**/${fileName}`));
|
|
29
|
+
}
|
|
30
|
+
// Dangerous directories
|
|
31
|
+
for (const dirName of getDangerousDirectories()) {
|
|
32
|
+
entries.push(literal(dirName));
|
|
33
|
+
entries.push(beneathCwd(`**/${dirName}/**`));
|
|
34
|
+
}
|
|
35
|
+
// Git hooks are always blocked for security
|
|
36
|
+
entries.push(literal('.git/hooks'));
|
|
37
|
+
entries.push(beneathCwd('**/.git/hooks/**'));
|
|
38
|
+
// Git config - conditionally blocked based on allowGitConfig setting
|
|
39
|
+
if (!allowGitConfig) {
|
|
40
|
+
entries.push(literal('.git/config'));
|
|
41
|
+
entries.push(beneathCwd('**/.git/config'));
|
|
42
|
+
}
|
|
43
|
+
return entries;
|
|
44
|
+
}
|
|
45
|
+
const sessionSuffix = `_${Math.random().toString(36).slice(2, 11)}_SBX`;
|
|
46
|
+
/**
|
|
47
|
+
* Generate a unique log tag for sandbox monitoring
|
|
48
|
+
* @param command - The command being executed (will be base64 encoded)
|
|
49
|
+
*/
|
|
50
|
+
function generateLogTag(command) {
|
|
51
|
+
const encodedCommand = encodeSandboxedCommand(command);
|
|
52
|
+
return `CMD64_${encodedCommand}_END_${sessionSuffix}`;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* SBPL path filter for a normalized entry: `regex` for glob patterns,
|
|
56
|
+
* `subpath` (the path and everything beneath it) otherwise.
|
|
57
|
+
*/
|
|
58
|
+
function pathFilter(entry) {
|
|
59
|
+
return entry.glob
|
|
60
|
+
? `(regex ${escapePath(globRegex(entry))})`
|
|
61
|
+
: `(subpath ${escapePath(entry.path)})`;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Compiles `entry`'s pattern with one of the shared string compilers in
|
|
65
|
+
* `sandbox-utils.ts`. An entry the library anchored at a directory
|
|
66
|
+
* (`anchor`) keeps that directory as a literal — the cwd is a name on disk
|
|
67
|
+
* and may itself contain `[`, `*` or `?` — so only the tail below it goes
|
|
68
|
+
* through the compiler, and the anchor is spliced back in escaped. Every
|
|
69
|
+
* compiler there returns '^…$'.
|
|
70
|
+
*
|
|
71
|
+
* This is the whole difference between the entry-taking wrappers here and
|
|
72
|
+
* the string-taking compilers they call: those see a spelling in which
|
|
73
|
+
* every character is glob syntax, which is right for what a caller wrote
|
|
74
|
+
* and wrong for what the library computed.
|
|
75
|
+
*/
|
|
76
|
+
function anchorRegex(entry, compile) {
|
|
77
|
+
if (entry.anchor === undefined)
|
|
78
|
+
return compile(entry.path);
|
|
79
|
+
const pattern = entry.path.slice(entry.anchor.length);
|
|
80
|
+
return `^${escapeRegexLiteral(entry.anchor)}${compile(pattern).slice(1)}`;
|
|
81
|
+
}
|
|
82
|
+
/** The regex for a glob entry: {@link globToRegex}, anchor respected. */
|
|
83
|
+
function globRegex(entry) {
|
|
84
|
+
return anchorRegex(entry, globToRegex);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* The regex for a glob entry used in a DENY rule: {@link denyGlobRegex},
|
|
88
|
+
* anchor respected. That is {@link globToRegex} plus an optional `/…` tail,
|
|
89
|
+
* so the deny covers everything beneath each match the way `subpath` does
|
|
90
|
+
* for literals. Callers strip a trailing `/**` before the pattern gets here
|
|
91
|
+
* (removeTrailingGlobSuffix), so `**\/secrets/**` arrives as `**\/secrets`
|
|
92
|
+
* and, matched exactly, would deny only the directory vnode while
|
|
93
|
+
* `secrets/key` stayed readable. This is what the Linux backend already
|
|
94
|
+
* does (a deny masks the whole subtree). Only ever widens a deny.
|
|
95
|
+
*/
|
|
96
|
+
function denyGlobEntryRegex(entry) {
|
|
97
|
+
return anchorRegex(entry, denyGlobRegex);
|
|
98
|
+
}
|
|
99
|
+
/** {@link pathFilter} for deny rules: globs get {@link denyGlobEntryRegex}. */
|
|
100
|
+
function denyPathFilter(entry) {
|
|
101
|
+
return entry.glob
|
|
102
|
+
? `(regex ${escapePath(denyGlobEntryRegex(entry))})`
|
|
103
|
+
: `(subpath ${escapePath(entry.path)})`;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* A concrete path shaped like the ones `entry` matches (every glob segment
|
|
107
|
+
* replaced by a literal `x`), used to test whether a deny regex covers the
|
|
108
|
+
* region an allow / write root points at. An anchored glob's anchor, and a
|
|
109
|
+
* literal entry's whole path, are names on disk and stay as they are.
|
|
110
|
+
*/
|
|
111
|
+
function entrySamplePath(entry) {
|
|
112
|
+
if (!entry.glob)
|
|
113
|
+
return entry.path;
|
|
114
|
+
const anchor = entry.anchor ?? '';
|
|
115
|
+
return (anchor + entry.path.slice(anchor.length).replace(/\[[^\]]*\]|[*?]+/g, 'x'));
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Narrow `filter` so it no longer matches anything covered by `carveOuts`
|
|
119
|
+
* (each an SBPL path filter). Used to re-emit a deny after the allows it
|
|
120
|
+
* would otherwise clobber, minus exactly the allow entries it overlaps —
|
|
121
|
+
* a deny minus carve-outs never matches anything the un-carved deny did
|
|
122
|
+
* not, so this stays deny-only.
|
|
123
|
+
*/
|
|
124
|
+
function carveFilter(filter, carveOuts) {
|
|
125
|
+
// Dedupe: the project dir is routinely both an allowRead entry and a
|
|
126
|
+
// write root.
|
|
127
|
+
const unique = [...new Set(carveOuts)];
|
|
128
|
+
if (unique.length === 0)
|
|
129
|
+
return filter;
|
|
130
|
+
const nots = unique.map(c => `(require-not ${c})`).join(' ');
|
|
131
|
+
return `(require-all ${filter} ${nots})`;
|
|
132
|
+
}
|
|
133
|
+
/** A pattern the library joined onto a literal directory of its own. */
|
|
134
|
+
function anchoredGlobEntry(anchor, pattern) {
|
|
135
|
+
return { glob: true, path: path.join(anchor, pattern), anchor };
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* A spelling that came from the caller's config: `*`, `?` and `[…]` in
|
|
139
|
+
* what the caller wrote are the glob syntax it asked for. The decision is
|
|
140
|
+
* made on that raw spelling, because resolving a relative or `~` path can
|
|
141
|
+
* splice in a cwd or home directory whose own name contains those
|
|
142
|
+
* characters — read back, they would turn the caller's `secrets` into a
|
|
143
|
+
* pattern that never matches the directory it was resolved to.
|
|
144
|
+
*/
|
|
145
|
+
function toPathEntry(pathPattern) {
|
|
146
|
+
return containsGlobChars(pathPattern)
|
|
147
|
+
? { glob: true, path: normalizePathForSandbox(pathPattern) }
|
|
148
|
+
: {
|
|
149
|
+
glob: false,
|
|
150
|
+
path: normalizePathForSandbox(pathPattern, { literal: true }),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* A path the library itself produced: joined onto the cwd, or resolved to
|
|
155
|
+
* a file it opened. It names one file or directory, so it compiles to a
|
|
156
|
+
* `subpath` filter whatever characters it contains — sniffed as a pattern,
|
|
157
|
+
* a component like `a[b` would become a character class and the filter
|
|
158
|
+
* would no longer match the path it was built from (the rule would be
|
|
159
|
+
* inert). Never use this for a caller's spelling.
|
|
160
|
+
*/
|
|
161
|
+
function toLiteralPathEntry(literalPath) {
|
|
162
|
+
return {
|
|
163
|
+
path: normalizePathForSandbox(literalPath, { literal: true }),
|
|
164
|
+
glob: false,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/** Does a subtree-extended deny glob regex cover `entry`'s region? */
|
|
168
|
+
function denyGlobCovers(denyRegex, entry) {
|
|
169
|
+
return denyRegex.test(entrySamplePath(entry));
|
|
170
|
+
}
|
|
171
|
+
/** Is `entry`'s region strictly inside the literal directory `dir`? */
|
|
172
|
+
function isStrictlyUnder(entry, dir) {
|
|
173
|
+
return isPathStrictlyUnder(entrySamplePath(entry), dir);
|
|
174
|
+
}
|
|
175
|
+
function resolveReadConfig(config, writeAllowPaths,
|
|
176
|
+
/**
|
|
177
|
+
* Read denies the library resolved itself — the masked credential files,
|
|
178
|
+
* which macOS degrades to a deny. Already literal: each names the file
|
|
179
|
+
* that was found, not a pattern to match.
|
|
180
|
+
*/
|
|
181
|
+
libraryDenies) {
|
|
182
|
+
return {
|
|
183
|
+
denies: [...(config.denyOnly || []).map(toPathEntry), ...libraryDenies],
|
|
184
|
+
// Non-glob spellings arrive slash-free from normalizePathForSandbox —
|
|
185
|
+
// the nested-deny re-emit matches by `path + '/'` prefix, which a
|
|
186
|
+
// preserved trailing slash would defeat ('<dir>//').
|
|
187
|
+
allows: (config.allowWithinDeny || []).map(toPathEntry),
|
|
188
|
+
writeRoots: (writeAllowPaths || []).map(toPathEntry),
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* The denies that must land AFTER the allowWithinDeny allows, because
|
|
193
|
+
* Seatbelt is last-match-wins and the allow block would otherwise re-open
|
|
194
|
+
* them. Each comes back as the SBPL filter to emit:
|
|
195
|
+
*
|
|
196
|
+
* - A literal deny nested inside a literal allow (`~/proj/secrets` under
|
|
197
|
+
* `~/proj`), re-emitted as-is.
|
|
198
|
+
* - Every glob deny, minus (`require-not`) each allow entry the glob's own
|
|
199
|
+
* regex covers. A leaf-shaped glob (`**\/.env`, `/**\/*.key`) covers no
|
|
200
|
+
* directory allow, so it comes back whole and beats the directory allows
|
|
201
|
+
* it lands inside — the fix for globs being silently re-allowed. A
|
|
202
|
+
* region-shaped glob (`~/**\/*` with allowRead carve-outs) covers its
|
|
203
|
+
* carve-outs, so they are subtracted and its behavior is unchanged. A
|
|
204
|
+
* glob that covers a specific FILE allow (a user carve-out, or the
|
|
205
|
+
* TLS-termination trust bundle sandbox-manager adds to allowWithinDeny,
|
|
206
|
+
* which a `/**\/*.crt` deny would otherwise sever) keeps that one file
|
|
207
|
+
* readable without any allow being emitted after the denies.
|
|
208
|
+
*
|
|
209
|
+
* Every filter here is a deny or a narrower deny: nothing this function
|
|
210
|
+
* produces can make a path readable that is not readable today. Keep it
|
|
211
|
+
* that way — the moment an `(allow file-read* …)` is appended after this
|
|
212
|
+
* block, every deny above it has to be re-audited against it.
|
|
213
|
+
*
|
|
214
|
+
* The coverage test (denyGlobCovers) fails closed by construction: every
|
|
215
|
+
* carve-out is an entry the allow block above already allows, so an
|
|
216
|
+
* unnecessary carve-out only reproduces today's behavior for that entry,
|
|
217
|
+
* and a missed one (e.g. a glob allow whose sample path the deny regex
|
|
218
|
+
* happens not to match) leaves the deny wider — never opens anything.
|
|
219
|
+
*/
|
|
220
|
+
function lateReadDenyFilters(resolved) {
|
|
221
|
+
const filters = [];
|
|
222
|
+
let coversRoot = false;
|
|
223
|
+
const literalAllowDirs = resolved.allows.filter(a => !a.glob).map(a => a.path);
|
|
224
|
+
for (const deny of resolved.denies) {
|
|
225
|
+
if (!deny.glob) {
|
|
226
|
+
if (literalAllowDirs.some(a => isStrictlyUnder(deny, a))) {
|
|
227
|
+
filters.push(denyPathFilter(deny));
|
|
228
|
+
}
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
const denyRegex = new RegExp(denyGlobEntryRegex(deny));
|
|
232
|
+
if (denyRegex.test('/'))
|
|
233
|
+
coversRoot = true;
|
|
234
|
+
const carveOuts = resolved.allows
|
|
235
|
+
.filter(a => denyGlobCovers(denyRegex, a))
|
|
236
|
+
.map(a => pathFilter(a));
|
|
237
|
+
filters.push(carveFilter(denyPathFilter(deny), carveOuts));
|
|
238
|
+
}
|
|
239
|
+
return { filters, coversRoot };
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Directory that bounds where a glob can match: its static prefix, or "/"
|
|
243
|
+
* for a root-anchored pattern like `/**\/*.key`.
|
|
244
|
+
*/
|
|
245
|
+
function globBaseDir(normalizedGlob) {
|
|
246
|
+
const staticPrefix = normalizedGlob.split(/[*?[\]]/)[0];
|
|
247
|
+
if (!staticPrefix || staticPrefix === '/')
|
|
248
|
+
return '/';
|
|
249
|
+
return staticPrefix.endsWith('/')
|
|
250
|
+
? staticPrefix.slice(0, -1)
|
|
251
|
+
: path.dirname(staticPrefix);
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Directory that bounds where `entry` can match: the anchor the library
|
|
255
|
+
* set, the static prefix of a pattern, or the path itself when it names
|
|
256
|
+
* one file or directory.
|
|
257
|
+
*/
|
|
258
|
+
function entryBaseDir(entry) {
|
|
259
|
+
if (!entry.glob)
|
|
260
|
+
return entry.path;
|
|
261
|
+
return entry.anchor ?? globBaseDir(entry.path);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Trailing `(deny file-write-unlink …)` for read-denied paths that the
|
|
265
|
+
* write section may have re-opened. Emitted at the very end of the profile.
|
|
266
|
+
*
|
|
267
|
+
* generateReadRules() blocks moving a read-denied path (and its ancestors)
|
|
268
|
+
* out from under its deny, but then re-allows file-write-unlink /
|
|
269
|
+
* file-write-create for every allowWrite root so `rm` works inside the
|
|
270
|
+
* project (#171). Any read-denied path INSIDE a write root is therefore
|
|
271
|
+
* movable again: `mv .env x; cat x`, or `mv secrets s2; cat s2/key`,
|
|
272
|
+
* defeats both glob and literal denies. This re-denies unlink (rename
|
|
273
|
+
* source / rm) — not create, so new files can still be made; a new `.env`
|
|
274
|
+
* is still read-denied by name — for:
|
|
275
|
+
*
|
|
276
|
+
* - every glob deny whose region intersects a write root, minus the allow
|
|
277
|
+
* entries and write roots the glob itself covers (a region glob like
|
|
278
|
+
* `~/**\/*` must not re-block `rm` inside carve-outs it was already
|
|
279
|
+
* subtracting; a leaf glob like `**\/.env` covers none of them);
|
|
280
|
+
* - every literal deny strictly below a write root, minus any allow entry
|
|
281
|
+
* or write root nested strictly inside it;
|
|
282
|
+
* - the literal ancestor directories of each of those (for a glob, its
|
|
283
|
+
* static-prefix directory and that directory's ancestors) that sit
|
|
284
|
+
* strictly below a write root — the directory vnodes only, so `rm` of
|
|
285
|
+
* unrelated siblings still works but the enclosing directory cannot be
|
|
286
|
+
* renamed out from under the deny. Ancestors at or above a write root
|
|
287
|
+
* are left alone: the deny above already covers them, and re-denying the
|
|
288
|
+
* root itself would block unrelated `rm`s.
|
|
289
|
+
*
|
|
290
|
+
* A literal deny not below any write root needs nothing: the read
|
|
291
|
+
* section's move-blocking deny still holds for it. Deny-only, like the
|
|
292
|
+
* rest of this file's read handling.
|
|
293
|
+
*/
|
|
294
|
+
function generateReadDenyUnlinkRules(resolved, logTag) {
|
|
295
|
+
const { denies, allows, writeRoots } = resolved;
|
|
296
|
+
if (writeRoots.length === 0)
|
|
297
|
+
return [];
|
|
298
|
+
const writeRootRegexes = writeRoots
|
|
299
|
+
.filter((w) => w.glob)
|
|
300
|
+
.map(w => new RegExp(globRegex(w)));
|
|
301
|
+
const literalWriteRoots = writeRoots.filter(w => !w.glob).map(w => w.path);
|
|
302
|
+
const strictlyBelowWriteRoot = (p) => literalWriteRoots.some(w => isStrictlyUnder({ path: p, glob: false }, w)) ||
|
|
303
|
+
writeRootRegexes.some(re => re.test(p));
|
|
304
|
+
const carveOutsInside = (dir) => [...allows, ...writeRoots]
|
|
305
|
+
.filter(e => isStrictlyUnder(e, dir))
|
|
306
|
+
.map(e => pathFilter(e));
|
|
307
|
+
const filters = new Set();
|
|
308
|
+
const protectDirs = (dirs) => {
|
|
309
|
+
for (const dir of dirs) {
|
|
310
|
+
if (strictlyBelowWriteRoot(dir)) {
|
|
311
|
+
filters.add(`(literal ${escapePath(dir)})`);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
for (const deny of denies) {
|
|
316
|
+
if (deny.glob) {
|
|
317
|
+
const baseDir = entryBaseDir(deny);
|
|
318
|
+
const intersectsWriteRoot = writeRootRegexes.length > 0 ||
|
|
319
|
+
literalWriteRoots.some(w => baseDir === w ||
|
|
320
|
+
isStrictlyUnder({ path: baseDir, glob: false }, w) ||
|
|
321
|
+
isStrictlyUnder({ path: w, glob: false }, baseDir));
|
|
322
|
+
if (!intersectsWriteRoot)
|
|
323
|
+
continue;
|
|
324
|
+
const denyRegex = new RegExp(denyGlobEntryRegex(deny));
|
|
325
|
+
const carveOuts = [...allows, ...writeRoots]
|
|
326
|
+
.filter(e => denyGlobCovers(denyRegex, e))
|
|
327
|
+
.map(e => pathFilter(e));
|
|
328
|
+
filters.add(carveFilter(denyPathFilter(deny), carveOuts));
|
|
329
|
+
if (baseDir !== '/') {
|
|
330
|
+
protectDirs([baseDir, ...getAncestorDirectories(baseDir)]);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
if (!strictlyBelowWriteRoot(deny.path))
|
|
335
|
+
continue;
|
|
336
|
+
filters.add(carveFilter(denyPathFilter(deny), carveOutsInside(deny.path)));
|
|
337
|
+
protectDirs(getAncestorDirectories(deny.path));
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return renderRule('deny', ['file-write-unlink'], filters, logTag);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Render one SBPL rule applying `action` for each of `operations` to any
|
|
344
|
+
* path matching one of `filters`, reporting `logTag` on a match. Emits
|
|
345
|
+
* nothing for an empty filter set: a rule with no filter would match every
|
|
346
|
+
* path.
|
|
347
|
+
*/
|
|
348
|
+
function renderRule(action, operations, filters, logTag) {
|
|
349
|
+
if (filters.size === 0)
|
|
350
|
+
return [];
|
|
351
|
+
return [
|
|
352
|
+
`(${action} ${operations.join(' ')}`,
|
|
353
|
+
...[...filters].map(f => ` ${f}`),
|
|
354
|
+
` (with message "${logTag}"))`,
|
|
355
|
+
];
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Get all ancestor directories for a path, up to (but not including) root
|
|
359
|
+
* Example: /private/tmp/test/file.txt -> ["/private/tmp/test", "/private/tmp", "/private"]
|
|
360
|
+
*/
|
|
361
|
+
function getAncestorDirectories(pathStr) {
|
|
362
|
+
const ancestors = [];
|
|
363
|
+
let currentPath = path.dirname(pathStr);
|
|
364
|
+
// Walk up the directory tree until we reach root
|
|
365
|
+
while (currentPath !== '/' && currentPath !== '.') {
|
|
366
|
+
ancestors.push(currentPath);
|
|
367
|
+
const parentPath = path.dirname(currentPath);
|
|
368
|
+
// Break if we've reached the top (path.dirname returns the same path for root)
|
|
369
|
+
if (parentPath === currentPath) {
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
currentPath = parentPath;
|
|
373
|
+
}
|
|
374
|
+
return ancestors;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* sandbox-exec rejects a string literal longer than 1025 bytes ("Error
|
|
378
|
+
* reading string"); the regexes built below stay well under that, since
|
|
379
|
+
* one oversized string invalidates the whole profile.
|
|
380
|
+
*/
|
|
381
|
+
const SBPL_STRING_MAX_BYTES = 900;
|
|
382
|
+
/**
|
|
383
|
+
* Below this many names, one regex is not shorter than the literal filters
|
|
384
|
+
* it would replace.
|
|
385
|
+
*/
|
|
386
|
+
const MIN_DENY_GROUP_SIZE = 4;
|
|
387
|
+
/** Escape a literal path component for use inside a regex. */
|
|
388
|
+
function escapeRegexLiteral(text) {
|
|
389
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Fold literal deny paths into {@link LiteralDenyGroup}s. Each group renders
|
|
393
|
+
* as one anchored regex per chunk of names instead of one `subpath` filter
|
|
394
|
+
* per path, so a directory with many same-shaped children costs bytes and
|
|
395
|
+
* profile compile time proportional to the names, not to the repeated
|
|
396
|
+
* absolute prefix (sandbox-exec compiles a few thousand path filters in
|
|
397
|
+
* seconds; a few dozen regexes in milliseconds). Globs, paths that do not
|
|
398
|
+
* fit a group of at least {@link MIN_DENY_GROUP_SIZE} names, and names too
|
|
399
|
+
* long for one regex are returned in `rest` unchanged.
|
|
400
|
+
*/
|
|
401
|
+
function groupLiteralDenyPaths(entries) {
|
|
402
|
+
const byDir = new Map();
|
|
403
|
+
for (const entry of entries) {
|
|
404
|
+
if (entry.glob)
|
|
405
|
+
continue;
|
|
406
|
+
const entryPath = entry.path;
|
|
407
|
+
const parent = path.dirname(entryPath);
|
|
408
|
+
const dir = path.dirname(parent);
|
|
409
|
+
if (dir === parent || parent === entryPath || dir === '/')
|
|
410
|
+
continue;
|
|
411
|
+
let names = byDir.get(dir);
|
|
412
|
+
if (!names) {
|
|
413
|
+
names = new Map();
|
|
414
|
+
byDir.set(dir, names);
|
|
415
|
+
}
|
|
416
|
+
const name = path.basename(parent);
|
|
417
|
+
let leaves = names.get(name);
|
|
418
|
+
if (!leaves) {
|
|
419
|
+
leaves = new Set();
|
|
420
|
+
names.set(name, leaves);
|
|
421
|
+
}
|
|
422
|
+
leaves.add(path.basename(entryPath));
|
|
423
|
+
}
|
|
424
|
+
const grouped = new Set();
|
|
425
|
+
const groups = [];
|
|
426
|
+
for (const [dir, names] of byDir) {
|
|
427
|
+
const bySignature = new Map();
|
|
428
|
+
for (const [name, leafSet] of names) {
|
|
429
|
+
const leaves = [...leafSet].sort();
|
|
430
|
+
const signature = leaves.join('\0');
|
|
431
|
+
let group = bySignature.get(signature);
|
|
432
|
+
if (!group) {
|
|
433
|
+
group = { dir, names: [], leaves };
|
|
434
|
+
bySignature.set(signature, group);
|
|
435
|
+
}
|
|
436
|
+
group.names.push(name);
|
|
437
|
+
}
|
|
438
|
+
for (const group of bySignature.values()) {
|
|
439
|
+
const fixedLength = regexLength(groupRegexPrefix(group)) + regexLength(groupDenyTail(group));
|
|
440
|
+
group.names = group.names.filter(name => fixedLength + regexLength(escapeRegexLiteral(name)) <=
|
|
441
|
+
SBPL_STRING_MAX_BYTES);
|
|
442
|
+
if (group.names.length < MIN_DENY_GROUP_SIZE)
|
|
443
|
+
continue;
|
|
444
|
+
groups.push(group);
|
|
445
|
+
for (const name of group.names) {
|
|
446
|
+
for (const leaf of group.leaves) {
|
|
447
|
+
grouped.add(path.join(dir, name, leaf));
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
return {
|
|
453
|
+
groups,
|
|
454
|
+
rest: entries.filter(e => !grouped.has(e.path)),
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
/** Bytes a regex fragment occupies inside an SBPL string literal. */
|
|
458
|
+
function regexLength(fragment) {
|
|
459
|
+
return Buffer.byteLength(escapePath(fragment)) - 2;
|
|
460
|
+
}
|
|
461
|
+
function groupRegexPrefix(group) {
|
|
462
|
+
return `^${escapeRegexLiteral(group.dir)}/(`;
|
|
463
|
+
}
|
|
464
|
+
function groupDenyTail(group) {
|
|
465
|
+
return `)/(${group.leaves.map(escapeRegexLiteral).join('|')})(/.*)?$`;
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Regex filters for a {@link LiteralDenyGroup}, chunked so no regex exceeds
|
|
469
|
+
* {@link SBPL_STRING_MAX_BYTES}. `deny` matches each `<dir>/<name>/<leaf>`
|
|
470
|
+
* and everything beneath it (the `subpath` semantics of a literal deny);
|
|
471
|
+
* `pins` match each `<dir>/<name>` directory itself, the move-blocking
|
|
472
|
+
* literal a per-path deny would have added for its parent.
|
|
473
|
+
*/
|
|
474
|
+
function literalDenyGroupFilters(group) {
|
|
475
|
+
const prefix = groupRegexPrefix(group);
|
|
476
|
+
const denyTail = groupDenyTail(group);
|
|
477
|
+
const pinTail = ')$';
|
|
478
|
+
const fixedLength = regexLength(prefix) + regexLength(denyTail);
|
|
479
|
+
const chunks = [];
|
|
480
|
+
let chunk = [];
|
|
481
|
+
let chunkLength = 0;
|
|
482
|
+
for (const name of group.names.map(escapeRegexLiteral)) {
|
|
483
|
+
const nameLength = regexLength(name) + (chunk.length === 0 ? 0 : 1);
|
|
484
|
+
if (chunk.length > 0 &&
|
|
485
|
+
fixedLength + chunkLength + nameLength > SBPL_STRING_MAX_BYTES) {
|
|
486
|
+
chunks.push(chunk);
|
|
487
|
+
chunk = [];
|
|
488
|
+
chunkLength = 0;
|
|
489
|
+
}
|
|
490
|
+
chunk.push(name);
|
|
491
|
+
chunkLength += chunk.length === 1 ? regexLength(name) : nameLength;
|
|
492
|
+
}
|
|
493
|
+
chunks.push(chunk);
|
|
494
|
+
const alternations = chunks.map(names => names.join('|'));
|
|
495
|
+
return {
|
|
496
|
+
deny: alternations.map(names => `(regex ${escapePath(prefix + names + denyTail)})`),
|
|
497
|
+
pins: alternations.map(names => `(regex ${escapePath(prefix + names + pinTail)})`),
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Generate deny rules for file movement (file-write-unlink) and creation
|
|
502
|
+
* (file-write-create) to protect paths. This prevents bypassing read or write
|
|
503
|
+
* restrictions by moving files/directories, and prevents replacing a
|
|
504
|
+
* not-yet-existing protected path (or one of its ancestors) with an
|
|
505
|
+
* attacker-controlled symlink.
|
|
506
|
+
*
|
|
507
|
+
* Emitted as a single rule whose filters are the union over all patterns:
|
|
508
|
+
* protected paths commonly share most of their ancestors, and each distinct
|
|
509
|
+
* filter both costs argv bytes and adds to sandbox-exec's compile time.
|
|
510
|
+
*
|
|
511
|
+
* @param entries - Normalized entries to protect (literals and globs)
|
|
512
|
+
* @param logTag - Log tag for sandbox violations
|
|
513
|
+
* @returns Array of sandbox profile rule lines
|
|
514
|
+
*/
|
|
515
|
+
function generateMoveBlockingRules(entries, logTag) {
|
|
516
|
+
return renderRule('deny', ['file-write-unlink', 'file-write-create'], moveBlockingFilters(entries), logTag);
|
|
517
|
+
}
|
|
518
|
+
/** The filters {@link generateMoveBlockingRules} emits, for normalized entries. */
|
|
519
|
+
function moveBlockingFilters(entries) {
|
|
520
|
+
const filters = new Set();
|
|
521
|
+
for (const entry of entries) {
|
|
522
|
+
// Block moving/renaming the denied path itself (or files matching the
|
|
523
|
+
// pattern, and anything beneath them)
|
|
524
|
+
filters.add(denyPathFilter(entry));
|
|
525
|
+
const baseDir = entryBaseDir(entry);
|
|
526
|
+
if (entry.glob) {
|
|
527
|
+
// For glob patterns, block moves of the directory the pattern is
|
|
528
|
+
// bounded by, then of its ancestors
|
|
529
|
+
if (baseDir === '/')
|
|
530
|
+
continue;
|
|
531
|
+
filters.add(`(literal ${escapePath(baseDir)})`);
|
|
532
|
+
}
|
|
533
|
+
// Block moves of ancestor directories
|
|
534
|
+
for (const ancestorDir of getAncestorDirectories(baseDir)) {
|
|
535
|
+
filters.add(`(literal ${escapePath(ancestorDir)})`);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
return filters;
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Generate filesystem read rules for sandbox profile
|
|
542
|
+
*
|
|
543
|
+
* Supports two layers:
|
|
544
|
+
* 1. denyOnly: deny reads from these paths (broad regions like /Users)
|
|
545
|
+
* 2. allowWithinDeny: re-allow reads within denied regions (like CWD)
|
|
546
|
+
* allowWithinDeny takes precedence over denyOnly.
|
|
547
|
+
*
|
|
548
|
+
* In Seatbelt profiles, later rules take precedence, so we emit:
|
|
549
|
+
* (allow file-read*) ← default: allow everything
|
|
550
|
+
* (deny file-read* ...) ← deny everything in denyOnly
|
|
551
|
+
* (allow file-read* ...) ← re-allow allowWithinDeny
|
|
552
|
+
* (deny file-read* ...) ← re-emit the denies the allows would clobber:
|
|
553
|
+
* literal denies nested in an allow, and every
|
|
554
|
+
* glob deny minus the allows it covers
|
|
555
|
+
* (see lateReadDenyFilters)
|
|
556
|
+
* (allow file-read* (literal "/")) ← only if a deny covers "/" itself
|
|
557
|
+
*
|
|
558
|
+
* REVIEW INVARIANT: after the allowWithinDeny block, this function only
|
|
559
|
+
* ever adds denies (or narrows one with require-not). The one exception is
|
|
560
|
+
* the pre-existing literal-"/" re-allow, which matches exactly one vnode.
|
|
561
|
+
* Do not append another `(allow file-read* …)` layer here — every deny
|
|
562
|
+
* above it would then need re-auditing for re-open bypasses.
|
|
563
|
+
*/
|
|
564
|
+
function generateReadRules(resolved, logTag) {
|
|
565
|
+
if (!resolved) {
|
|
566
|
+
return [`(allow file-read*)`];
|
|
567
|
+
}
|
|
568
|
+
const rules = [];
|
|
569
|
+
// Start by allowing everything
|
|
570
|
+
rules.push(`(allow file-read*)`);
|
|
571
|
+
// Then deny specific paths
|
|
572
|
+
const deniesRoot = resolved.denies.some(d => d.path === '/');
|
|
573
|
+
const denyFilters = new Set(resolved.denies.map(denyPathFilter));
|
|
574
|
+
rules.push(...renderRule('deny', ['file-read*'], denyFilters, logTag));
|
|
575
|
+
// Re-allow specific paths within denied regions (allowWithinDeny takes precedence)
|
|
576
|
+
const allowFilters = new Set(resolved.allows.map(a => pathFilter(a)));
|
|
577
|
+
rules.push(...renderRule('allow', ['file-read*'], allowFilters, logTag));
|
|
578
|
+
// Denies the allow block would otherwise win over (last-match-wins) land
|
|
579
|
+
// here, after it. Must stay ahead of the file-read-metadata allow below.
|
|
580
|
+
const late = lateReadDenyFilters(resolved);
|
|
581
|
+
rules.push(...renderRule('deny', ['file-read*'], new Set(late.filters), logTag));
|
|
582
|
+
// (subpath "/") — or a re-emitted `/*`-shaped glob — denies the root inode
|
|
583
|
+
// itself; no allowWithinDeny entry covers "/", so dyld aborts before exec
|
|
584
|
+
// (#190). Re-allow the literal root, after the re-emitted denies so a
|
|
585
|
+
// glob landing later can't take it away again. This exposes `ls /` dirent
|
|
586
|
+
// names but no subtree contents.
|
|
587
|
+
if (deniesRoot || late.coversRoot) {
|
|
588
|
+
rules.push(`(allow file-read* (literal "/"))`);
|
|
589
|
+
}
|
|
590
|
+
// Allow stat/lstat on all directories so that realpath() can traverse
|
|
591
|
+
// path components within denied regions. Without this, C realpath() fails
|
|
592
|
+
// when resolving symlinks because it needs to lstat every intermediate
|
|
593
|
+
// directory (e.g. /Users, /Users/chris) even if only a subdirectory like
|
|
594
|
+
// ~/.local is in allowWithinDeny. This only allows metadata reads on
|
|
595
|
+
// directories — not listing contents (readdir) or reading files.
|
|
596
|
+
if (resolved.denies.length > 0) {
|
|
597
|
+
rules.push(`(allow file-read-metadata`, ` (vnode-type DIRECTORY))`);
|
|
598
|
+
}
|
|
599
|
+
// Block file movement to prevent bypass via mv/rename
|
|
600
|
+
rules.push(...generateMoveBlockingRules(resolved.denies, logTag));
|
|
601
|
+
// Re-allow file-write-unlink / file-write-create for paths that are explicitly
|
|
602
|
+
// write-allowed. The move-blocking rules above emit broad
|
|
603
|
+
// (deny file-write-unlink (subpath "/Users")) to prevent bypassing read
|
|
604
|
+
// restrictions by moving files out of denied regions.
|
|
605
|
+
// However, in macOS Seatbelt, a specific (deny file-write-unlink) is not overridden
|
|
606
|
+
// by a later (allow file-write*) wildcard — the specific operation deny wins.
|
|
607
|
+
// This means file deletions are blocked even in write-allowed directories like
|
|
608
|
+
// the project directory. We fix this by explicitly re-allowing file-write-unlink
|
|
609
|
+
// and file-write-create for write-allowed paths after the move-blocking deny rules.
|
|
610
|
+
//
|
|
611
|
+
// Note: denyWithinAllow paths are not excluded here because the write section's
|
|
612
|
+
// generateMoveBlockingRules() runs later in the profile and re-denies
|
|
613
|
+
// file-write-unlink for those paths (Seatbelt uses last-match-wins). This
|
|
614
|
+
// depends on read rules being emitted before write rules in generateSandboxProfile().
|
|
615
|
+
//
|
|
616
|
+
// This re-allow also re-opens rename/rm of read-denied paths that sit
|
|
617
|
+
// INSIDE a write root; generateReadDenyUnlinkRules(), emitted at the end
|
|
618
|
+
// of the profile, takes those back.
|
|
619
|
+
const writeAllowFilters = new Set(resolved.writeRoots.map(pathFilter));
|
|
620
|
+
rules.push(...renderRule('allow', ['file-write-unlink', 'file-write-create'], writeAllowFilters, logTag));
|
|
621
|
+
return rules;
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Generate filesystem write rules for sandbox profile
|
|
625
|
+
*/
|
|
626
|
+
function generateWriteRules(config, logTag, allowGitConfig = false) {
|
|
627
|
+
if (!config) {
|
|
628
|
+
return [`(allow file-write*)`];
|
|
629
|
+
}
|
|
630
|
+
const rules = [];
|
|
631
|
+
// Generate allow rules
|
|
632
|
+
const allowFilters = new Set();
|
|
633
|
+
for (const pathPattern of config.allowOnly || []) {
|
|
634
|
+
allowFilters.add(pathFilter(toPathEntry(pathPattern)));
|
|
635
|
+
}
|
|
636
|
+
rules.push(...renderRule('allow', ['file-write*'], allowFilters, logTag));
|
|
637
|
+
// Combine user-specified and mandatory deny patterns (no ripgrep needed on
|
|
638
|
+
// macOS). The caller's spellings are patterns when they read as patterns;
|
|
639
|
+
// the mandatory entries carry their own literal/glob split.
|
|
640
|
+
const denyEntries = [
|
|
641
|
+
...(config.denyWithinAllow || []).map(toPathEntry),
|
|
642
|
+
...macGetMandatoryDenyEntries(allowGitConfig),
|
|
643
|
+
];
|
|
644
|
+
const { groups, rest: ungrouped } = groupLiteralDenyPaths(denyEntries);
|
|
645
|
+
const groupFilters = groups.map(literalDenyGroupFilters);
|
|
646
|
+
const denyFilters = new Set();
|
|
647
|
+
for (const { deny } of groupFilters) {
|
|
648
|
+
for (const filter of deny)
|
|
649
|
+
denyFilters.add(filter);
|
|
650
|
+
}
|
|
651
|
+
for (const entry of ungrouped) {
|
|
652
|
+
denyFilters.add(denyPathFilter(entry));
|
|
653
|
+
}
|
|
654
|
+
rules.push(...renderRule('deny', ['file-write*'], denyFilters, logTag));
|
|
655
|
+
// Block file movement to prevent bypass via mv/rename. A grouped path
|
|
656
|
+
// contributes its regex, the pin for its parent directory, and the
|
|
657
|
+
// literals for the group directory and its ancestors — the same set a
|
|
658
|
+
// per-path filter would add.
|
|
659
|
+
const moveFilters = moveBlockingFilters(ungrouped);
|
|
660
|
+
for (const [index, { deny, pins }] of groupFilters.entries()) {
|
|
661
|
+
for (const filter of [...deny, ...pins])
|
|
662
|
+
moveFilters.add(filter);
|
|
663
|
+
const { dir } = groups[index];
|
|
664
|
+
for (const ancestorDir of [dir, ...getAncestorDirectories(dir)]) {
|
|
665
|
+
moveFilters.add(`(literal ${escapePath(ancestorDir)})`);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
rules.push(...renderRule('deny', ['file-write-unlink', 'file-write-create'], moveFilters, logTag));
|
|
669
|
+
return rules;
|
|
670
|
+
}
|
|
671
|
+
/**
|
|
672
|
+
* Generate complete sandbox profile
|
|
673
|
+
*/
|
|
674
|
+
function generateSandboxProfile({ readConfig, libraryDenyEntries, writeConfig, httpProxyPort, socksProxyPort, needsNetworkRestriction, allowUnixSockets, allowAllUnixSockets, allowLocalBinding, allowMachLookup, allowPty, allowGitConfig = false, enableWeakerNetworkIsolation = false, allowAppleEvents = false, logTag, }) {
|
|
675
|
+
const profile = [
|
|
676
|
+
'(version 1)',
|
|
677
|
+
`(deny default (with message "${logTag}"))`,
|
|
678
|
+
'',
|
|
679
|
+
`; LogTag: ${logTag}`,
|
|
680
|
+
'',
|
|
681
|
+
'; Essential permissions - based on Chrome sandbox policy',
|
|
682
|
+
'; Process permissions',
|
|
683
|
+
'(allow process-exec)',
|
|
684
|
+
'(allow process-fork)',
|
|
685
|
+
'(allow process-info* (target same-sandbox))',
|
|
686
|
+
'(allow signal (target same-sandbox))',
|
|
687
|
+
'(allow mach-priv-task-port (target same-sandbox))',
|
|
688
|
+
'',
|
|
689
|
+
'; User preferences',
|
|
690
|
+
'(allow user-preference-read)',
|
|
691
|
+
'',
|
|
692
|
+
'; Mach IPC - specific services only (no wildcard)',
|
|
693
|
+
'(allow mach-lookup',
|
|
694
|
+
' (global-name "com.apple.audio.systemsoundserver")',
|
|
695
|
+
' (global-name "com.apple.distributed_notifications@Uv3")',
|
|
696
|
+
' (global-name "com.apple.FontObjectsServer")',
|
|
697
|
+
' (global-name "com.apple.fonts")',
|
|
698
|
+
' (global-name "com.apple.logd")',
|
|
699
|
+
' (global-name "com.apple.lsd.mapdb")',
|
|
700
|
+
' (global-name "com.apple.PowerManagement.control")',
|
|
701
|
+
' (global-name "com.apple.system.logger")',
|
|
702
|
+
' (global-name "com.apple.system.notification_center")',
|
|
703
|
+
' (global-name "com.apple.system.opendirectoryd.libinfo")',
|
|
704
|
+
' (global-name "com.apple.system.opendirectoryd.membership")',
|
|
705
|
+
' (global-name "com.apple.bsd.dirhelper")',
|
|
706
|
+
' (global-name "com.apple.securityd.xpc")',
|
|
707
|
+
' (global-name "com.apple.coreservices.launchservicesd")',
|
|
708
|
+
')',
|
|
709
|
+
'',
|
|
710
|
+
...(enableWeakerNetworkIsolation
|
|
711
|
+
? [
|
|
712
|
+
'; trustd.agent - needed for Go TLS certificate verification (weaker network isolation)',
|
|
713
|
+
'(allow mach-lookup (global-name "com.apple.trustd.agent"))',
|
|
714
|
+
]
|
|
715
|
+
: []),
|
|
716
|
+
...(allowAppleEvents
|
|
717
|
+
? [
|
|
718
|
+
'; Apple Events - opt-in; needed for open/osascript to talk to other apps (appleeventsd)',
|
|
719
|
+
'(allow appleevent-send)',
|
|
720
|
+
'(allow mach-lookup (global-name "com.apple.coreservices.appleevents"))',
|
|
721
|
+
'; Launch Services open requests need the lsopen operation plus, on',
|
|
722
|
+
'; macOS 14/15, coreservicesd and the quarantine resolver - without',
|
|
723
|
+
'; these open fails with -10822 kLSServerCommunicationErr or -54',
|
|
724
|
+
'(allow lsopen)',
|
|
725
|
+
'(allow mach-lookup (global-name "com.apple.CoreServices.coreservicesd"))',
|
|
726
|
+
'(allow mach-lookup (global-name "com.apple.coreservices.quarantine-resolver"))',
|
|
727
|
+
]
|
|
728
|
+
: []),
|
|
729
|
+
...(allowMachLookup && allowMachLookup.length > 0
|
|
730
|
+
? [
|
|
731
|
+
'; User-specified XPC/Mach services',
|
|
732
|
+
...allowMachLookup.map(name => name.endsWith('*')
|
|
733
|
+
? `(allow mach-lookup (global-name-prefix ${escapePath(name.slice(0, -1))}))`
|
|
734
|
+
: `(allow mach-lookup (global-name ${escapePath(name)}))`),
|
|
735
|
+
]
|
|
736
|
+
: []),
|
|
737
|
+
'',
|
|
738
|
+
'; POSIX IPC - shared memory',
|
|
739
|
+
'(allow ipc-posix-shm)',
|
|
740
|
+
'',
|
|
741
|
+
'; POSIX IPC - semaphores for Python multiprocessing',
|
|
742
|
+
'(allow ipc-posix-sem)',
|
|
743
|
+
'',
|
|
744
|
+
'; IOKit - specific operations only',
|
|
745
|
+
'(allow iokit-open',
|
|
746
|
+
' (iokit-registry-entry-class "IOSurfaceRootUserClient")',
|
|
747
|
+
' (iokit-registry-entry-class "RootDomainUserClient")',
|
|
748
|
+
' (iokit-user-client-class "IOSurfaceSendRight")',
|
|
749
|
+
')',
|
|
750
|
+
'',
|
|
751
|
+
'; IOKit properties',
|
|
752
|
+
'(allow iokit-get-properties)',
|
|
753
|
+
'',
|
|
754
|
+
"; Specific safe system-sockets, doesn't allow network access",
|
|
755
|
+
'(allow system-socket (require-all (socket-domain AF_SYSTEM) (socket-protocol 2)))',
|
|
756
|
+
'',
|
|
757
|
+
'; sysctl - specific sysctls only',
|
|
758
|
+
'(allow sysctl-read',
|
|
759
|
+
' (sysctl-name "hw.activecpu")',
|
|
760
|
+
' (sysctl-name "hw.busfrequency_compat")',
|
|
761
|
+
' (sysctl-name "hw.byteorder")',
|
|
762
|
+
' (sysctl-name "hw.cacheconfig")',
|
|
763
|
+
' (sysctl-name "hw.cachelinesize_compat")',
|
|
764
|
+
' (sysctl-name "hw.cpufamily")',
|
|
765
|
+
' (sysctl-name "hw.cpufrequency")',
|
|
766
|
+
' (sysctl-name "hw.cpufrequency_compat")',
|
|
767
|
+
' (sysctl-name "hw.cputype")',
|
|
768
|
+
' (sysctl-name "hw.l1dcachesize_compat")',
|
|
769
|
+
' (sysctl-name "hw.l1icachesize_compat")',
|
|
770
|
+
' (sysctl-name "hw.l2cachesize_compat")',
|
|
771
|
+
' (sysctl-name "hw.l3cachesize_compat")',
|
|
772
|
+
' (sysctl-name "hw.logicalcpu")',
|
|
773
|
+
' (sysctl-name "hw.logicalcpu_max")',
|
|
774
|
+
' (sysctl-name "hw.machine")',
|
|
775
|
+
' (sysctl-name "hw.memsize")',
|
|
776
|
+
' (sysctl-name "hw.ncpu")',
|
|
777
|
+
' (sysctl-name "hw.nperflevels")',
|
|
778
|
+
' (sysctl-name "hw.packages")',
|
|
779
|
+
' (sysctl-name "hw.pagesize_compat")',
|
|
780
|
+
' (sysctl-name "hw.pagesize")',
|
|
781
|
+
' (sysctl-name "hw.physicalcpu")',
|
|
782
|
+
' (sysctl-name "hw.physicalcpu_max")',
|
|
783
|
+
' (sysctl-name "hw.tbfrequency_compat")',
|
|
784
|
+
' (sysctl-name "hw.vectorunit")',
|
|
785
|
+
' (sysctl-name "kern.argmax")',
|
|
786
|
+
' (sysctl-name "kern.bootargs")',
|
|
787
|
+
' (sysctl-name "kern.hostname")',
|
|
788
|
+
' (sysctl-name "kern.maxfiles")',
|
|
789
|
+
' (sysctl-name "kern.maxfilesperproc")',
|
|
790
|
+
' (sysctl-name "kern.maxproc")',
|
|
791
|
+
' (sysctl-name "kern.ngroups")',
|
|
792
|
+
' (sysctl-name "kern.osproductversion")',
|
|
793
|
+
' (sysctl-name "kern.osrelease")',
|
|
794
|
+
' (sysctl-name "kern.ostype")',
|
|
795
|
+
' (sysctl-name "kern.osvariant_status")',
|
|
796
|
+
' (sysctl-name "kern.osversion")',
|
|
797
|
+
' (sysctl-name "kern.secure_kernel")',
|
|
798
|
+
' (sysctl-name "kern.tcsm_available")',
|
|
799
|
+
' (sysctl-name "kern.tcsm_enable")',
|
|
800
|
+
' (sysctl-name "kern.usrstack64")',
|
|
801
|
+
' (sysctl-name "kern.version")',
|
|
802
|
+
' (sysctl-name "kern.willshutdown")',
|
|
803
|
+
' (sysctl-name "machdep.cpu.brand_string")',
|
|
804
|
+
' (sysctl-name "machdep.ptrauth_enabled")',
|
|
805
|
+
' (sysctl-name "security.mac.lockdown_mode_state")',
|
|
806
|
+
' (sysctl-name "sysctl.proc_cputype")',
|
|
807
|
+
' (sysctl-name "vm.loadavg")',
|
|
808
|
+
' (sysctl-name-prefix "hw.optional.arm")',
|
|
809
|
+
' (sysctl-name-prefix "hw.optional.arm.")',
|
|
810
|
+
' (sysctl-name-prefix "hw.optional.armv8_")',
|
|
811
|
+
' (sysctl-name-prefix "hw.perflevel")',
|
|
812
|
+
' (sysctl-name-prefix "kern.proc.all")',
|
|
813
|
+
' (sysctl-name-prefix "kern.proc.pgrp.")',
|
|
814
|
+
' (sysctl-name-prefix "kern.proc.pid.")',
|
|
815
|
+
' (sysctl-name-prefix "machdep.cpu.")',
|
|
816
|
+
' (sysctl-name-prefix "net.routetable.")',
|
|
817
|
+
')',
|
|
818
|
+
'',
|
|
819
|
+
'; V8 thread calculations',
|
|
820
|
+
'(allow sysctl-write',
|
|
821
|
+
' (sysctl-name "kern.tcsm_enable")',
|
|
822
|
+
')',
|
|
823
|
+
'',
|
|
824
|
+
'; Distributed notifications',
|
|
825
|
+
'(allow distributed-notification-post)',
|
|
826
|
+
'',
|
|
827
|
+
'; Specific mach-lookup permissions for security operations',
|
|
828
|
+
'(allow mach-lookup (global-name "com.apple.SecurityServer"))',
|
|
829
|
+
'',
|
|
830
|
+
'; File I/O on device files',
|
|
831
|
+
'(allow file-ioctl (literal "/dev/null"))',
|
|
832
|
+
'(allow file-ioctl (literal "/dev/zero"))',
|
|
833
|
+
'(allow file-ioctl (literal "/dev/random"))',
|
|
834
|
+
'(allow file-ioctl (literal "/dev/urandom"))',
|
|
835
|
+
'(allow file-ioctl (literal "/dev/dtracehelper"))',
|
|
836
|
+
'(allow file-ioctl (literal "/dev/tty"))',
|
|
837
|
+
'',
|
|
838
|
+
'(allow file-ioctl file-read-data file-write-data',
|
|
839
|
+
' (require-all',
|
|
840
|
+
' (literal "/dev/null")',
|
|
841
|
+
' (vnode-type CHARACTER-DEVICE)',
|
|
842
|
+
' )',
|
|
843
|
+
')',
|
|
844
|
+
'',
|
|
845
|
+
];
|
|
846
|
+
// Network rules
|
|
847
|
+
profile.push('; Network');
|
|
848
|
+
if (!needsNetworkRestriction) {
|
|
849
|
+
profile.push('(allow network*)');
|
|
850
|
+
}
|
|
851
|
+
else {
|
|
852
|
+
// Allow local binding if requested.
|
|
853
|
+
//
|
|
854
|
+
// bind/inbound use (local ip "*:*") instead of "localhost:*" because modern
|
|
855
|
+
// runtimes (Java, etc.) create IPv6 dual-stack sockets by default; binding
|
|
856
|
+
// such a socket to 127.0.0.1 is represented in the kernel as
|
|
857
|
+
// ::ffff:127.0.0.1, which Seatbelt's "localhost" filter does not match.
|
|
858
|
+
// Seatbelt only accepts "localhost" or "*" as the host token, so "*:*" is
|
|
859
|
+
// the only way to admit the IPv4-mapped form. bind/inbound are local
|
|
860
|
+
// operations (no remote endpoint), so wildcarding them does not grant
|
|
861
|
+
// egress.
|
|
862
|
+
//
|
|
863
|
+
// outbound uses (remote ip "localhost:*") so the egress allowlist remains
|
|
864
|
+
// enforced when allowLocalBinding is set (#225, #88). A (local ip ...)
|
|
865
|
+
// filter on network-outbound is evaluated against the source address,
|
|
866
|
+
// which for an unbound socket is INADDR_ANY (0.0.0.0 / ::) at connect()
|
|
867
|
+
// time — Seatbelt's "localhost" matches the any-address, so any
|
|
868
|
+
// (local ip ...) host value admits every outbound connection. (remote ip
|
|
869
|
+
// "localhost:*") matches connect() to 127.0.0.1 and ::1 but not
|
|
870
|
+
// ::ffff:127.0.0.1; runtimes that connect to loopback via dual-stack
|
|
871
|
+
// sockets need to use AF_INET (see JAVA_TOOL_OPTIONS injection below).
|
|
872
|
+
if (allowLocalBinding) {
|
|
873
|
+
profile.push('(allow network-bind (local ip "*:*"))');
|
|
874
|
+
profile.push('(allow network-inbound (local ip "*:*"))');
|
|
875
|
+
profile.push('(allow network-outbound (remote ip "localhost:*"))');
|
|
876
|
+
}
|
|
877
|
+
// Unix domain sockets for local IPC (SSH agent, Docker, Gradle, etc.)
|
|
878
|
+
// Three separate operations must be allowed:
|
|
879
|
+
// 1. system-socket: socket(AF_UNIX, ...) syscall — creates the socket fd (no path context)
|
|
880
|
+
// 2. network-bind: bind() to a local Unix socket path
|
|
881
|
+
// 3. network-outbound: connect() to a remote Unix socket path
|
|
882
|
+
// Note: (subpath ...) and (path-regex ...) are path-based filters that can only match
|
|
883
|
+
// bind/connect operations — socket() creation has no path, so it requires system-socket.
|
|
884
|
+
if (allowAllUnixSockets) {
|
|
885
|
+
// Allow creating AF_UNIX sockets and all Unix socket paths
|
|
886
|
+
profile.push('(allow system-socket (socket-domain AF_UNIX))');
|
|
887
|
+
profile.push('(allow network-bind (local unix-socket (path-regex #"^/")))');
|
|
888
|
+
profile.push('(allow network-outbound (remote unix-socket (path-regex #"^/")))');
|
|
889
|
+
}
|
|
890
|
+
else if (allowUnixSockets && allowUnixSockets.length > 0) {
|
|
891
|
+
// Allow creating AF_UNIX sockets (required for any Unix socket use)
|
|
892
|
+
profile.push('(allow system-socket (socket-domain AF_UNIX))');
|
|
893
|
+
// Allow specific Unix socket paths
|
|
894
|
+
for (const socketPath of allowUnixSockets) {
|
|
895
|
+
const normalizedPath = normalizePathForSandbox(socketPath);
|
|
896
|
+
profile.push(`(allow network-bind (local unix-socket (subpath ${escapePath(normalizedPath)})))`);
|
|
897
|
+
profile.push(`(allow network-outbound (remote unix-socket (subpath ${escapePath(normalizedPath)})))`);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
// If both allowAllUnixSockets and allowUnixSockets are false/undefined/empty, Unix sockets are blocked by default
|
|
901
|
+
// Allow localhost TCP operations for the HTTP proxy
|
|
902
|
+
if (httpProxyPort !== undefined) {
|
|
903
|
+
profile.push(`(allow network-bind (local ip "localhost:${httpProxyPort}"))`);
|
|
904
|
+
profile.push(`(allow network-inbound (local ip "localhost:${httpProxyPort}"))`);
|
|
905
|
+
profile.push(`(allow network-outbound (remote ip "localhost:${httpProxyPort}"))`);
|
|
906
|
+
}
|
|
907
|
+
// Allow localhost TCP operations for the SOCKS proxy. Skip when it's
|
|
908
|
+
// the same port as the HTTP proxy (the mux serves both on one port);
|
|
909
|
+
// SBPL accepts duplicate allow clauses but there's no need to emit them.
|
|
910
|
+
if (socksProxyPort !== undefined && socksProxyPort !== httpProxyPort) {
|
|
911
|
+
profile.push(`(allow network-bind (local ip "localhost:${socksProxyPort}"))`);
|
|
912
|
+
profile.push(`(allow network-inbound (local ip "localhost:${socksProxyPort}"))`);
|
|
913
|
+
profile.push(`(allow network-outbound (remote ip "localhost:${socksProxyPort}"))`);
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
profile.push('');
|
|
917
|
+
// Read rules
|
|
918
|
+
// Pass write-allowed paths so that move-blocking deny rules in the read section
|
|
919
|
+
// can be overridden for paths where file deletion should be permitted.
|
|
920
|
+
const resolvedRead = readConfig || libraryDenyEntries.length > 0
|
|
921
|
+
? resolveReadConfig(readConfig ?? { denyOnly: [] }, writeConfig?.allowOnly, libraryDenyEntries)
|
|
922
|
+
: undefined;
|
|
923
|
+
profile.push('; File read');
|
|
924
|
+
profile.push(...generateReadRules(resolvedRead, logTag));
|
|
925
|
+
profile.push('');
|
|
926
|
+
// Write rules
|
|
927
|
+
profile.push('; File write');
|
|
928
|
+
profile.push(...generateWriteRules(writeConfig, logTag, allowGitConfig));
|
|
929
|
+
// Read-denied paths inside write roots: the read section's unlink/create
|
|
930
|
+
// re-allow for write roots (and the write section's file-write* allows)
|
|
931
|
+
// must not leave them renameable. Last in the profile so nothing above
|
|
932
|
+
// can re-open them.
|
|
933
|
+
if (resolvedRead) {
|
|
934
|
+
const unlinkRules = generateReadDenyUnlinkRules(resolvedRead, logTag);
|
|
935
|
+
if (unlinkRules.length > 0) {
|
|
936
|
+
profile.push('');
|
|
937
|
+
profile.push('; File read: keep read-denied paths inside write roots in place');
|
|
938
|
+
profile.push(...unlinkRules);
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
// Pseudo-terminal (pty) support
|
|
942
|
+
if (allowPty) {
|
|
943
|
+
profile.push('');
|
|
944
|
+
profile.push('; Pseudo-terminal (pty) support');
|
|
945
|
+
profile.push('(allow pseudo-tty)');
|
|
946
|
+
profile.push('(allow file-ioctl');
|
|
947
|
+
profile.push(' (literal "/dev/ptmx")');
|
|
948
|
+
profile.push(' (regex #"^/dev/ttys")');
|
|
949
|
+
profile.push(')');
|
|
950
|
+
profile.push('(allow file-read* file-write*');
|
|
951
|
+
profile.push(' (literal "/dev/ptmx")');
|
|
952
|
+
profile.push(' (regex #"^/dev/ttys")');
|
|
953
|
+
profile.push(')');
|
|
954
|
+
}
|
|
955
|
+
return profile.join('\n');
|
|
956
|
+
}
|
|
957
|
+
/**
|
|
958
|
+
* Escape path for sandbox profile using JSON.stringify for proper escaping
|
|
959
|
+
*/
|
|
960
|
+
function escapePath(pathStr) {
|
|
961
|
+
return JSON.stringify(pathStr);
|
|
962
|
+
}
|
|
963
|
+
/**
|
|
964
|
+
* Wrap command with macOS sandbox
|
|
965
|
+
*/
|
|
966
|
+
export function wrapCommandWithSandboxMacOS(params) {
|
|
967
|
+
const { command, commandId, needsNetworkRestriction, httpProxyPort, socksProxyPort, proxyAuthToken, caCertPath, javaAgentJarPath, allowUnixSockets, allowAllUnixSockets, allowLocalBinding, allowMachLookup, readConfig, writeConfig, unsetEnvVars, setEnvVars, maskedFileBinds, degradeToDenyPaths, allowPty, allowGitConfig = false, gitSafeDirectories, enableWeakerNetworkIsolation = false, allowAppleEvents = false, binShell, } = params;
|
|
968
|
+
// SBPL cannot redirect a read to different bytes, so whole-file masking
|
|
969
|
+
// degrades to read-deny on macOS: the sandboxed process gets EPERM
|
|
970
|
+
// instead of the sentinel. The DYLD interposer (a later step) lifts
|
|
971
|
+
// this. The paths go to generateReadRules() as LITERAL denies — each is
|
|
972
|
+
// a credential file the library located, not a spelling the caller wrote
|
|
973
|
+
// — and the existing (deny file-read* …) rule is emitted unchanged.
|
|
974
|
+
const maskedDenyPaths = maskedFileBinds?.map(b => b.realPath) ?? [];
|
|
975
|
+
if (maskedDenyPaths.length > 0) {
|
|
976
|
+
logForDebugging('[Sandbox macOS] file mask degrades to deny on macOS until the ' +
|
|
977
|
+
'interposer lands');
|
|
978
|
+
}
|
|
979
|
+
// A masked file whose extract pattern stopped matching is denied the
|
|
980
|
+
// same way: the library opened both, so both are literals.
|
|
981
|
+
const libraryDenyEntries = [
|
|
982
|
+
...maskedDenyPaths,
|
|
983
|
+
...(degradeToDenyPaths ?? []),
|
|
984
|
+
].map(toLiteralPathEntry);
|
|
985
|
+
// Determine if we have restrictions to apply
|
|
986
|
+
// Read: denyOnly pattern - empty array means no restrictions
|
|
987
|
+
// Write: allowOnly pattern - undefined means no restrictions, any config means restrictions
|
|
988
|
+
const hasReadRestrictions = (readConfig && readConfig.denyOnly.length > 0) ||
|
|
989
|
+
libraryDenyEntries.length > 0;
|
|
990
|
+
const hasWriteRestrictions = writeConfig !== undefined;
|
|
991
|
+
const hasEnvRestrictions = (unsetEnvVars !== undefined && unsetEnvVars.length > 0) ||
|
|
992
|
+
(setEnvVars !== undefined && Object.keys(setEnvVars).length > 0);
|
|
993
|
+
const hasGitConfig = (gitSafeDirectories?.length ?? 0) > 0;
|
|
994
|
+
// No sandboxing needed
|
|
995
|
+
if (!needsNetworkRestriction &&
|
|
996
|
+
!hasReadRestrictions &&
|
|
997
|
+
!hasWriteRestrictions &&
|
|
998
|
+
!hasEnvRestrictions &&
|
|
999
|
+
!hasGitConfig) {
|
|
1000
|
+
return command;
|
|
1001
|
+
}
|
|
1002
|
+
// Both correlation carriers (seatbelt log tag, proxy username) encode
|
|
1003
|
+
// the attribution key, which is the caller's commandId when the
|
|
1004
|
+
// executed string differs from the one violations are looked up by.
|
|
1005
|
+
const attributionCommand = attributionKeyFor(command, commandId);
|
|
1006
|
+
const logTag = generateLogTag(attributionCommand);
|
|
1007
|
+
const profile = generateSandboxProfile({
|
|
1008
|
+
readConfig,
|
|
1009
|
+
libraryDenyEntries,
|
|
1010
|
+
writeConfig,
|
|
1011
|
+
httpProxyPort,
|
|
1012
|
+
socksProxyPort,
|
|
1013
|
+
needsNetworkRestriction,
|
|
1014
|
+
allowUnixSockets,
|
|
1015
|
+
allowAllUnixSockets,
|
|
1016
|
+
allowLocalBinding,
|
|
1017
|
+
allowMachLookup,
|
|
1018
|
+
allowPty,
|
|
1019
|
+
allowGitConfig,
|
|
1020
|
+
enableWeakerNetworkIsolation,
|
|
1021
|
+
allowAppleEvents,
|
|
1022
|
+
logTag,
|
|
1023
|
+
});
|
|
1024
|
+
// Generate proxy environment variables using shared utility
|
|
1025
|
+
const proxyEnvArgs = generateProxyEnvVars(httpProxyPort, socksProxyPort, caCertPath, proxyAuthToken, writeConfig === undefined, encodeSandboxedCommand(attributionCommand));
|
|
1026
|
+
// JAVA_TOOL_OPTIONS carries two things for JVMs in the sandbox:
|
|
1027
|
+
//
|
|
1028
|
+
// - The proxy agent jar (see java-proxy-agent.ts): JVMs ignore the proxy
|
|
1029
|
+
// env vars above, so the agent translates them into system properties
|
|
1030
|
+
// plus an Authenticator for the proxy credential at JVM start.
|
|
1031
|
+
// - -Djava.net.preferIPv4Stack=true whenever the profile lets the child
|
|
1032
|
+
// reach loopback at all (the proxy ports, or allowLocalBinding's
|
|
1033
|
+
// localhost:*): Seatbelt's (remote ip "localhost:N") filter matches
|
|
1034
|
+
// 127.0.0.1 and ::1 but not the IPv4-mapped IPv6 form ::ffff:127.0.0.1.
|
|
1035
|
+
// Modern Java defaults to AF_INET6 dual-stack sockets, so a Java client
|
|
1036
|
+
// connecting to 127.0.0.1 reaches the kernel as ::ffff:127.0.0.1 and is
|
|
1037
|
+
// denied ("Operation not permitted") — including its connect to the
|
|
1038
|
+
// proxy the agent just pointed it at. Forcing the IPv4 stack makes Java
|
|
1039
|
+
// open AF_INET sockets so loopback connect matches the filter.
|
|
1040
|
+
//
|
|
1041
|
+
// Both are composed with any inherited JAVA_TOOL_OPTIONS unless that var
|
|
1042
|
+
// is on the credential-deny list, in which case the inherited value is
|
|
1043
|
+
// dropped so the deny holds.
|
|
1044
|
+
const loopbackReachable = needsNetworkRestriction &&
|
|
1045
|
+
(allowLocalBinding ||
|
|
1046
|
+
httpProxyPort !== undefined ||
|
|
1047
|
+
socksProxyPort !== undefined);
|
|
1048
|
+
const javaToolOptions = buildJavaToolOptions({
|
|
1049
|
+
agentJarPath: javaAgentJarPath,
|
|
1050
|
+
flags: loopbackReachable ? ['-Djava.net.preferIPv4Stack=true'] : [],
|
|
1051
|
+
unsetEnvVars,
|
|
1052
|
+
inherited: process.env.JAVA_TOOL_OPTIONS,
|
|
1053
|
+
});
|
|
1054
|
+
if (javaToolOptions !== undefined) {
|
|
1055
|
+
proxyEnvArgs.push(`JAVA_TOOL_OPTIONS=${javaToolOptions}`);
|
|
1056
|
+
}
|
|
1057
|
+
// safe.directory (dubious-ownership) — `buildPosixGitSafeDirEnv`
|
|
1058
|
+
// composes against the child's actual starting env (process.env
|
|
1059
|
+
// inherited under sandbox-exec, unsetEnvVars dropped, setEnvVars
|
|
1060
|
+
// overlaid) so an ambient GIT_CONFIG_COUNT is continued, not
|
|
1061
|
+
// clobbered.
|
|
1062
|
+
if (gitSafeDirectories && gitSafeDirectories.length > 0) {
|
|
1063
|
+
const gitCfg = buildPosixGitSafeDirEnv({
|
|
1064
|
+
safeDirs: gitSafeDirectories,
|
|
1065
|
+
unsetEnvVars,
|
|
1066
|
+
setEnvVars,
|
|
1067
|
+
});
|
|
1068
|
+
for (const [name, value] of Object.entries(gitCfg)) {
|
|
1069
|
+
proxyEnvArgs.push(`${name}=${value}`);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
// Use the user's shell (zsh, bash, etc.) to ensure aliases/snapshots work
|
|
1073
|
+
// Resolve the full path to the shell binary
|
|
1074
|
+
const shellName = binShell || 'bash';
|
|
1075
|
+
const shell = whichSync(shellName);
|
|
1076
|
+
if (!shell) {
|
|
1077
|
+
throw new Error(`Shell '${shellName}' not found in PATH`);
|
|
1078
|
+
}
|
|
1079
|
+
// Drop denied credential env vars from the inherited environment. The -u
|
|
1080
|
+
// flags must precede the VAR=VALUE assignments so SRT's own proxy plumbing
|
|
1081
|
+
// vars survive even if a caller lists one of them as a denied credential.
|
|
1082
|
+
const unsetEnvArgs = (unsetEnvVars ?? []).flatMap(name => ['-u', name]);
|
|
1083
|
+
// Masked credentials override the inherited real value with a sentinel.
|
|
1084
|
+
// Placed before the proxy plumbing assignments for the same precedence
|
|
1085
|
+
// reason as the -u flags.
|
|
1086
|
+
const setEnvArgs = Object.entries(setEnvVars ?? {}).map(([name, value]) => `${name}=${value}`);
|
|
1087
|
+
// Use `env` command to set environment variables - each VAR=value is a separate
|
|
1088
|
+
// argument that quote() escapes properly, avoiding shell quoting issues
|
|
1089
|
+
const wrappedCommand = quote([
|
|
1090
|
+
'env',
|
|
1091
|
+
...unsetEnvArgs,
|
|
1092
|
+
...setEnvArgs,
|
|
1093
|
+
...proxyEnvArgs,
|
|
1094
|
+
'/usr/bin/sandbox-exec',
|
|
1095
|
+
'-p',
|
|
1096
|
+
profile,
|
|
1097
|
+
shell,
|
|
1098
|
+
'-c',
|
|
1099
|
+
command,
|
|
1100
|
+
]);
|
|
1101
|
+
logForDebugging(`[Sandbox macOS] Applied restrictions - network: ${!!(httpProxyPort || socksProxyPort)}, read: ${hasReadRestrictions
|
|
1102
|
+
? readConfig && 'allowAllExcept' in readConfig
|
|
1103
|
+
? 'allowAllExcept'
|
|
1104
|
+
: 'denyAllExcept'
|
|
1105
|
+
: 'none'}, write: ${writeConfig
|
|
1106
|
+
? 'allowAllExcept' in writeConfig
|
|
1107
|
+
? 'allowAllExcept'
|
|
1108
|
+
: 'denyAllExcept'
|
|
1109
|
+
: 'none'}`);
|
|
1110
|
+
return wrappedCommand;
|
|
1111
|
+
}
|
|
1112
|
+
/**
|
|
1113
|
+
* Start monitoring macOS system logs for sandbox violations
|
|
1114
|
+
* Look for sandbox-related kernel deny events ending in {logTag}
|
|
1115
|
+
*/
|
|
1116
|
+
export function startMacOSSandboxLogMonitor(callback, ignoreViolations,
|
|
1117
|
+
/** Map a decoded attribution key to the command text it represents, before
|
|
1118
|
+
* ignoreViolations matching and before the event's `command` is set. Only
|
|
1119
|
+
* the manager holds the registry that can do that, so it is required
|
|
1120
|
+
* rather than defaulted: a caller with no registry passes
|
|
1121
|
+
* `sanitizeUnregisteredCommandKey`, which treats the key as the untrusted
|
|
1122
|
+
* bytes it arrived as. */
|
|
1123
|
+
resolveCommandText) {
|
|
1124
|
+
// Pre-compile regex patterns for better performance
|
|
1125
|
+
const cmdExtractRegex = /CMD64_(.+?)_END/;
|
|
1126
|
+
const sandboxExtractRegex = /Sandbox:\s+(.+)$/;
|
|
1127
|
+
// Stream and filter kernel logs for all sandbox violations
|
|
1128
|
+
// We can't filter by specific logTag since it's dynamic per command
|
|
1129
|
+
const logProcess = spawn('log', [
|
|
1130
|
+
'stream',
|
|
1131
|
+
'--predicate',
|
|
1132
|
+
`(eventMessage ENDSWITH "${sessionSuffix}")`,
|
|
1133
|
+
'--style',
|
|
1134
|
+
'compact',
|
|
1135
|
+
]);
|
|
1136
|
+
logProcess.stdout?.on('data', (data) => {
|
|
1137
|
+
const lines = data.toString().split('\n');
|
|
1138
|
+
// Get violation and command lines
|
|
1139
|
+
const violationLine = lines.find(line => line.includes('Sandbox:') && line.includes('deny'));
|
|
1140
|
+
const commandLine = lines.find(line => line.startsWith('CMD64_'));
|
|
1141
|
+
if (!violationLine)
|
|
1142
|
+
return;
|
|
1143
|
+
// Extract violation details
|
|
1144
|
+
const sandboxMatch = violationLine.match(sandboxExtractRegex);
|
|
1145
|
+
if (!sandboxMatch?.[1])
|
|
1146
|
+
return;
|
|
1147
|
+
const violationDetails = sandboxMatch[1];
|
|
1148
|
+
// Try to get command
|
|
1149
|
+
let command;
|
|
1150
|
+
let encodedCommand;
|
|
1151
|
+
if (commandLine) {
|
|
1152
|
+
const cmdMatch = commandLine.match(cmdExtractRegex);
|
|
1153
|
+
encodedCommand = cmdMatch?.[1];
|
|
1154
|
+
if (encodedCommand) {
|
|
1155
|
+
try {
|
|
1156
|
+
command = resolveCommandText(decodeSandboxedCommand(encodedCommand));
|
|
1157
|
+
}
|
|
1158
|
+
catch {
|
|
1159
|
+
// Failed to decode, continue without command
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
// Always filter out noisey violations
|
|
1164
|
+
if (violationDetails.includes('mDNSResponder') ||
|
|
1165
|
+
violationDetails.includes('mach-lookup com.apple.diagnosticd') ||
|
|
1166
|
+
violationDetails.includes('mach-lookup com.apple.analyticsd')) {
|
|
1167
|
+
return;
|
|
1168
|
+
}
|
|
1169
|
+
// Check if we should ignore this violation
|
|
1170
|
+
if (shouldIgnoreViolation(violationDetails, command, ignoreViolations)) {
|
|
1171
|
+
return;
|
|
1172
|
+
}
|
|
1173
|
+
// Not ignored - report the violation
|
|
1174
|
+
callback({
|
|
1175
|
+
line: violationDetails,
|
|
1176
|
+
command,
|
|
1177
|
+
encodedCommand,
|
|
1178
|
+
timestamp: new Date(), // We could parse the timestamp from the log but this feels more reliable
|
|
1179
|
+
});
|
|
1180
|
+
});
|
|
1181
|
+
logProcess.stderr?.on('data', (data) => {
|
|
1182
|
+
logForDebugging(`[Sandbox Monitor] Log stream stderr: ${data.toString()}`);
|
|
1183
|
+
});
|
|
1184
|
+
logProcess.on('error', (error) => {
|
|
1185
|
+
logForDebugging(`[Sandbox Monitor] Failed to start log stream: ${error.message}`);
|
|
1186
|
+
});
|
|
1187
|
+
logProcess.on('exit', (code) => {
|
|
1188
|
+
logForDebugging(`[Sandbox Monitor] Log stream exited with code: ${code}`);
|
|
1189
|
+
});
|
|
1190
|
+
return () => {
|
|
1191
|
+
logForDebugging('[Sandbox Monitor] Stopping log monitor');
|
|
1192
|
+
logProcess.kill('SIGTERM');
|
|
1193
|
+
};
|
|
1194
|
+
}
|
|
1195
|
+
//# sourceMappingURL=macos-sandbox-utils.js.map
|