mirror of
https://github.com/aiclientproxy/proxycast.git
synced 2026-10-16 07:16:36 +08:00
fix(sandbox): enforce Windows outbound isolation with WFP
This commit is contained in:
@@ -2641,7 +2641,9 @@ Job Object descendant cleanup 已进入 target-gated integration matrix。ConPTY
|
||||
`windows_setup` 编排 offline/online 本地账户与 machine-scope DPAPI artifacts,其中账户、组与 SID 操作集中在
|
||||
`windows_setup::accounts` 子模块;`windows_firewall` 使用 offline account SID
|
||||
安装一条非 loopback 全协议规则和两条 loopback TCP/UDP 出站 block rule,并拒绝 group-policy override、部分 profile 生效、active
|
||||
profile firewall disabled 或属性 read-back 漂移;`windows_wfp` 保留按同一账户匹配的 ICMP/DNS/SMB 补充过滤器。
|
||||
profile firewall disabled 或属性 read-back 漂移;`windows_wfp` 以同一账户的 ALE user identity 安装 V4/V6 全 outbound-connect block,
|
||||
并保留 ICMP/DNS/SMB 专项过滤器作为 fail-closed defense in depth。Firewall/WFP 的属性 read-back 只能证明规则存在,仍须以
|
||||
真机连接矩阵证明 enforcement。
|
||||
restricted runner 在 `network.enabled=true` 时使用 online account,否则使用 offline account;sandbox account user SID 进入
|
||||
restricted SID access check,但不进入默认 DACL 充当 capability。runner 不设置
|
||||
`SBX_NONET_ACTIVE` 或代理环境变量冒充 enforcement。命令 lowering 仍对
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
> upstream: `/Users/coso/Documents/dev/rust/codex`(当前观测 HEAD:`99660ab3c7b861c916e467581fa9b8723504d66b`)
|
||||
> checklist progress: `44/46 (95.7%)`;这是未加权任务数,不等于交付完成度,剩余项包含 Windows 平台安全、live/verifier 与正式分发硬门槛。
|
||||
|
||||
> 当前主目标(2026-08-26):关闭 C-3 Windows restricted execution 的真机证据。Codex current 的 per-user Windows Firewall 非 loopback/loopback 出站阻断、offline/online sandbox identity、`LimeSandboxUsers` 普通 token ACL、短生命周期 capability SID restricted ACL、clean-runner setup/read-back、原始 DACL rollback、sandbox-account command runner 与七项 evidence collector 已进入唯一 current owner。Windows Quality run `32973017956` 已把 schema v3 真机矩阵推进到 `6/7`:workspace write/metadata 与 external deny、large output、stdin、ConPTY、Everyone-write audit 和 terminate/job cleanup 全部通过;唯一剩余项是 offline account 身份正确但 loopback TCP 未被旧的全协议 loopback Firewall rule 拦截。当前对齐 Codex current,将 loopback policy 拆为独立 TCP/UDP block rule;在七项通过前保持 `Planned/enforced=false`。
|
||||
> 当前主目标(2026-08-26):关闭 C-3 Windows restricted execution 的真机证据。Codex current 的 per-user Windows Firewall 非 loopback/loopback 出站阻断、offline/online sandbox identity、`LimeSandboxUsers` 普通 token ACL、短生命周期 capability SID restricted ACL、clean-runner setup/read-back、原始 DACL rollback、sandbox-account command runner 与七项 evidence collector 已进入唯一 current owner。Windows Quality 真机矩阵保持 `6/7`:workspace write/metadata 与 external deny、large output、stdin、ConPTY、Everyone-write audit 和 terminate/job cleanup 全部通过;唯一剩余项是 offline account 身份正确但 loopback TCP 未被 Firewall 拦截。run `32974377348` 已证明 Codex 风格 TCP/UDP 规则拆分和 read-back 仍不足,当前在既有 WFP owner 增加按 offline ALE user identity 匹配的 V4/V6 全 outbound-connect block;在七项通过前保持 `Planned/enforced=false`。
|
||||
> 参考原则:`/Users/coso/Documents/dev/rust/codex` 是协议、Thread/Turn/Item、runtime lifecycle、tool/approval 和 GUI 语义的直接实现参考源;Lime 只在产品范围、provider 和桌面宿主边界做显式适配,不以旧矩阵或同名 legacy API 代替对齐。
|
||||
> 目标:把 Lime 的产品主链、协议字段、GUI 工作区、执行安全和真实 Desktop 证据推进到当前 Codex Desktop 语义;不恢复已退役 runtime、v0 或 `agentSession/*` 兼容主链。
|
||||
|
||||
@@ -68,7 +68,7 @@ Renderer typed gateway
|
||||
| MCP resource origin | Workspace MCP App 从 canonical Item 的 `appContext`/resource URI 建立 WebContentsView surface,并以 `originCallId` 请求同一 Thread authority;`codex_apps` 不依赖本地 Plugin 安装态 | 已完成 canonical producer/cold restore、bounded provenance、link/account revalidation、稳定组件回归和独立 Electron Gate B;证据见 `.lime/qc/gui-evidence/mcp-resource-origin-electron-gate-b/` |
|
||||
| Environment lifecycle | `TaskCenterEnvironmentPanel` + `useThreadEnvironmentLifecycleStatus` 已消费 `environment/status` 与 typed connected/disconnected notification,稳定 DOM 覆盖环境 identity/status | 已完成五语言、组件回归和独立 Electron Gate B:真实远端 Environment 断线与有限重连在同一 canonical Thread 可见,mock/console/page/invoke error 为 0 |
|
||||
|
||||
当前执行顺序:Provider capability、Queue(含重复正文视觉收口)、Project、Strict Review、D-2 MCP event stream/resource origin、D-3 Environment、Thread Revert、Browser/Computer Use requirements 产品裁决、Thread/Item current 字段/恢复复核、Agent current 聚合门禁、本机 macOS packaged candidate、`1.135.0` 正式 macOS 分发和 Windows Squirrel N-1 packaged Gate B 已关闭;C-3 Windows restricted-token、ACL/Job、ConPTY、elevated setup、offline/online account、Firewall/WFP、readiness read-back、本地 fail-closed 单测和真实 packaged evidence collector 已进入 current owner。最新矩阵已为 `6/7`,当前只剩 offline account 的 loopback TCP 阻断;对齐 Codex current 将 loopback Firewall policy 拆为独立 TCP/UDP block rule 后重跑七项 Windows/MSVC 安全矩阵。矩阵 `7/7` 后再验证 packaged runner digest。live provider/Pier/DeepSWE verifier 和覆盖当前工作树的正式分发同样等待外部环境。每完成一项即更新本计划与运行证据,不批量提前勾选。
|
||||
当前执行顺序:Provider capability、Queue(含重复正文视觉收口)、Project、Strict Review、D-2 MCP event stream/resource origin、D-3 Environment、Thread Revert、Browser/Computer Use requirements 产品裁决、Thread/Item current 字段/恢复复核、Agent current 聚合门禁、本机 macOS packaged candidate、`1.135.0` 正式 macOS 分发和 Windows Squirrel N-1 packaged Gate B 已关闭;C-3 Windows restricted-token、ACL/Job、ConPTY、elevated setup、offline/online account、Firewall/WFP、readiness read-back、本地 fail-closed 单测和真实 packaged evidence collector 已进入 current owner。最新矩阵已为 `6/7`,当前只剩 offline account 的 loopback TCP 阻断;Firewall protocol 拆分已被真机证伪,当前改由 WFP ALE user filter 补强全 outbound connect 后重跑七项 Windows/MSVC 安全矩阵。矩阵 `7/7` 后再验证 packaged runner digest。live provider/Pier/DeepSWE verifier 和覆盖当前工作树的正式分发同样等待外部环境。每完成一项即更新本计划与运行证据,不批量提前勾选。
|
||||
|
||||
> 最新 Queue/CI 收口状态(2026-08-26):Queue 状态条已删除 submission preview 与 `thread-queue-items` 正文列表,canonical 时间线成为唯一正文 owner;五语言只保留标题、loading、数量和刷新失败状态。组件、Gate B 与 Sherpa 定向回归 25/25,`npm run i18n:check` 保持 100%。真实 Queue Gate B 已通过:`timelineMarkerCount=1`、`queueStatusContainsMarker=false`、`queueItemsPresent=false`、47 次真实 Electron IPC、`mockFallbackHitCount=0`、console/page/invoke error 均为 0,证据见 `.lime/qc/gui-evidence/thread-queue-electron-gate-b/thread-queue-electron-gate-b-summary.json`。根 `package.json`/lock importer 已声明直接 `ws@8.18.3`,修复 Quality CI Frontend Full 的 `Failed to resolve import "ws"`;Windows Shell Runtime 上限调为 60 分钟,restricted security matrix 已前移到 Sherpa/sidecar 重型阶段之前,Sherpa 清理/解压前后输出阶段日志。`smoke:agent-runtime-current-fixture` 完整通过,`npm run verify:gui-smoke` Shell-01 21/21、contracts 299 checks、typecheck、scripts/legacy governance 均通过;App Server Windows sandbox fail-closed 定向单测 4/4 通过。上述本机测试不替代 Windows restricted matrix 或 live verifier;正式 macOS 与 Squirrel 证据由独立 Release run `32864956267` 证明。
|
||||
|
||||
@@ -403,6 +403,7 @@ Renderer typed gateway
|
||||
- 2026-08-26:Windows Quality run `32970595099`(SHA `844a2316a`,job `98183292205`,artifact `9607584715`)setup/MSVC 通过,schema v3 仍为 `3/7`。workspace 新增的连续 restricted `cmd.exe` 原生写入已成功,active SDDL 同时包含 `LimeSandboxUsers` 与短期 capability SID,说明 exact workspace write 与共享 lease 已实际生效;该 case 随后被“group SID 必须相对 baseline 新增”的诊断断言提前截断。stdin/offline/terminate 仍在 PowerShell cmdlet 初始化 cwd provider 时对 `C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\.tmp*` 抛 `UnauthorizedAccessException`。对照 Codex current `unified_exec` tests 后确认,其 sandbox command cwd 固定为仓库工作树,系统 Temp 仅承接 sandbox home;Lime evidence 把另一用户的私有 `%LOCALAPPDATA%\\Temp` 子目录同时当成产品 workspace,混入了宿主 profile ACL 边界。当前回归改为仓库工作树内隔离 fixture,并把普通组断言改为 active DACL 绝对包含、仅 capability 要求相对 baseline 新增;不放宽生产 ACL、token、firewall 或 readiness。`npm run test:rust:related -- lime-rs/crates/tool-runtime/tests/windows_restricted_execution.rs` 退出码 `0`,反向依赖链与 `tool-runtime 373/373` 通过,rustfmt 与 `git diff --check` 通过;Windows-only fixture 仍待 MSVC。
|
||||
- 2026-08-26:Windows Quality run `32971998836`(SHA `7c0c0574b`,job `98187791909`,artifact `9608137451`)elevated setup 通过,但 Windows-only evidence test 在 MSVC 编译阶段因 terminate 场景的 `handle.wait()` 需要可变借用而报 `E0596`,七项矩阵未执行,schema v3 因此为 `0/7 missing`,不是运行时回退证据。已只把该场景 handle 恢复为 `mut`;其他只调用共享引用方法或把 ownership 交给 `run_to_terminal` 的 handle 保持不可变。下一步先做本地 related/fmt/diff 门禁,再推送窄提交并重跑 Windows Quality;计划保持 `active`、`44/46 (95.7%)` 与 `SandboxBackendStatus::Planned/enforced=false`。
|
||||
- 2026-08-26:Windows Quality run `32973017956`(SHA `b7842eccc`,job `98191056610`)通过 elevated setup 和 MSVC 编译,schema v3 artifact 首次达到 `6/7`:workspace write/metadata 与 external deny、bounded large output、allowlisted stdin、ConPTY、Everyone-write audit、terminate/job cleanup 全部通过。唯一失败的 offline 场景使用了正确的 `LimeSandboxOffline` identity,但随机 loopback TCP 仍连接成功并以 code `9` 退出。WFP 12 项与 Codex current 一样只补 ICMP/DNS/SMB,随机 TCP 归 Firewall owner;Lime 旧实现将 loopback 合并为 `protocol=ANY` 单规则,而 Codex current 使用独立 TCP/UDP loopback block。当前修复保留非 loopback 全协议规则,将 loopback 拆为 TCP/UDP 两条并对协议做 read-back;不引入尚无产品需求的 proxy-port allowlist,不改 token/ACL/WFP/readiness。`npm run test:rust:related -- lime-rs/crates/tool-runtime/src/windows_firewall.rs lime-rs/crates/tool-runtime/tests/windows_restricted_execution.rs` 已通过反向依赖链与 `tool-runtime 373/373`,rustfmt 和 `git diff --check` 通过;下一步重跑 Windows Quality。完成度仍为 `44/46 (95.7%)`,readiness 仍为 `Planned/enforced=false`。
|
||||
- 2026-08-26:Windows Quality run `32974377348`(SHA `f6e305025`,job `98195543766`)再次为 `6/7`。setup 明确安装 `firewall_rules=3`、`wfp_filters=12` 并通过 read-back,但 offline process 仍以正确 identity 成功连接随机 loopback TCP;因此 Codex 风格 Firewall TCP/UDP 拆分不是充分条件,规则存在也不能冒充 enforcement。当前在同一 `windows_wfp` owner 新增 V4/V6 两条 user-only ALE_AUTH_CONNECT 全流量 block filter,使 offline account 的任意 IP connect 在内核分类层 fail closed;原 12 条 ICMP/DNS/SMB filter 与 3 条 Firewall rule 保留为 defense in depth,online account 不匹配。`npm run test:rust:related -- lime-rs/crates/tool-runtime/src/windows_wfp.rs lime-rs/crates/tool-runtime/src/windows_firewall.rs lime-rs/crates/tool-runtime/tests/windows_restricted_execution.rs` 已通过反向依赖链与 `tool-runtime 373/373`,rustfmt、docs boundary 和窄写集 diff check 均通过。下一步推送窄提交,再用 Windows setup 的 `wfp_filters=14` read-back 和 schema v3 七项矩阵验证。计划仍为 `44/46 (95.7%)`、`active`、`Planned/enforced=false`。
|
||||
|
||||
## 7. 阻塞与避让
|
||||
|
||||
|
||||
@@ -78,12 +78,27 @@ mod platform {
|
||||
|
||||
const USER_ICMP_V4: &[ConditionSpec] = &[ConditionSpec::User, ConditionSpec::Protocol(1)];
|
||||
const USER_ICMP_V6: &[ConditionSpec] = &[ConditionSpec::User, ConditionSpec::Protocol(58)];
|
||||
const USER_ALL_CONNECT: &[ConditionSpec] = &[ConditionSpec::User];
|
||||
const USER_DNS: &[ConditionSpec] = &[ConditionSpec::User, ConditionSpec::RemotePort(53)];
|
||||
const USER_DNS_TLS: &[ConditionSpec] = &[ConditionSpec::User, ConditionSpec::RemotePort(853)];
|
||||
const USER_SMB: &[ConditionSpec] = &[ConditionSpec::User, ConditionSpec::RemotePort(445)];
|
||||
const USER_NETBIOS: &[ConditionSpec] = &[ConditionSpec::User, ConditionSpec::RemotePort(139)];
|
||||
|
||||
const FILTER_SPECS: &[FilterSpec] = &[
|
||||
FilterSpec {
|
||||
key: GUID::from_u128(0xacd446ae_f297_407b_91a1_ede4be9277d9),
|
||||
name: "lime_wfp_all_connect_v4",
|
||||
description: "Block sandbox-account outbound connect v4",
|
||||
layer_key: FWPM_LAYER_ALE_AUTH_CONNECT_V4,
|
||||
conditions: USER_ALL_CONNECT,
|
||||
},
|
||||
FilterSpec {
|
||||
key: GUID::from_u128(0xe7e6e402_e609_4ca9_a974_3e8ec51eda38),
|
||||
name: "lime_wfp_all_connect_v6",
|
||||
description: "Block sandbox-account outbound connect v6",
|
||||
layer_key: FWPM_LAYER_ALE_AUTH_CONNECT_V6,
|
||||
conditions: USER_ALL_CONNECT,
|
||||
},
|
||||
FilterSpec {
|
||||
key: GUID::from_u128(0xd3792b9a_2f8d_4d54_a401_8d7b92589e02),
|
||||
name: "lime_wfp_icmp_connect_v4",
|
||||
|
||||
Reference in New Issue
Block a user