[sandbox-windows-acl] 标准用户 + 非系统盘工作区下 workspace-write 完全不可用:缺少 WRITE_OWNER 导致 grantWrite 失败 #8339
Replies: 1 comment
|
The signature is already watched by a shipped advisory, and the documentation gap you found is real. Your message matches verbatim the signature a plugin I maintain classifies —
What the advisory says, and how it lines up with your report:
On the documentation half: your claim checks out.
|
Uh oh!
There was an error while loading. Please reload this page.
Environment / 环境
0.1.7-rc.222631.4460, AMD64)(注册表
ProductName显示 "Windows 10 Pro",是微软已知的 Win11 遗留值)IsInRole(Administrator) == falseD:\dsh(非系统盘)workspace-write@deepseek-ai/dsh-sandbox-windows-acl@0.1.7-rc.2English summary
On a standard (non-admin) Windows account, if the workspace directory's DACL grants only
Modify(the common case for directories on non-system drives, inherited asAuthenticated Users: Modify), theworkspace-writebackend cannot materialize its grant and every confined shell call fails — including a command that writes nothing:The prerequisite is documented in
sandbox-windows-acl's "Verified boundaries", but not in any user-facing README (dsh-sandbox,dsh-pwsh-sandbox,dsh-base,dsh-sandbox-policy), and the error carries no actionable guidance. The result is that users must approvedanger-full-accessfor every command, which defeats the purpose ofworkspace-write.摘要
在标准用户账户下,若工作区所在目录的 DACL 只授予
Modify,workspace-write沙箱无法完成授权物化,每一条受限 shell 命令都会失败——包括pwd这种不写任何东西的命令:用户看到的现象是:所有命令都必须请求「完整权限」才能执行,等于
workspace-write在该工作区完全不可用。前提已记录在
packages/sandbox/sandbox-windows-acl/README.md的 "Verified boundaries" 一节,但面向用户的文档均未提及,且报错未给出可操作指引。最小复现
以标准用户身份,在一个 DACL 只授予
Modify的目录上(例如非系统盘根目录下新建的子目录):对照组:对
%TEMP%下新建的目录(用户有继承来的FullControl)执行第 2 步,直接成功,无需任何改动。根因
packages/sandbox/sandbox-windows-acl/src/acl.ts的mergeAndApply用一次SetNamedSecurityInfoW同时应用 DACL 与完整性标签(编译产物lib/types-*.js):链条如下:
WRITE_OWNER。READ_CONTROL+WRITE_DAC—— 不含WRITE_OWNER(这一点sandbox-windows-acl自己的 README L122 已写明)。Modify的访问掩码是0x1301bf,不含WRITE_OWNER位0x00080000。WRITE_DAC),但标签那部分失败 → 整个调用返回ERROR_ACCESS_DENIED (5)。这与
README.mdL122 /README.zh.mdL122 记录的边界一致:即:该边界是已知且刻意的,fail-closed 本身正确。问题在于触发条件在真实环境里很常见,而用户完全拿不到解释。
为什么后端无法自行解决
这是权限自举问题:要在目录上获得
WRITE_OWNER,本身就需要该目录的WRITE_OWNER,或管理员特权(如SeTakeOwnershipPrivilege)。标准用户在这类目录上两者都没有。本帖不主张改成静默跳过隔离——无法强制执行时失败是正确的取舍。
实测证据
真实会话:策略
workspace-write下,一条只有pwd的命令失败:SetNamedSecurityInfoW failed (Win32 5): grantWrite(D:\dsh)受控 A/B:上述最小复现。同一个继承而来的 ACL,补
WRITE_OWNER前exit 5、补后exit 0。端到端(走公开 API):补齐后直接调用
AclSandbox:随后 spawn 受限子进程:
exit=0,文件创建成功exit=3,EPERM,文件未创建说明隔离本身工作正常,卡住的只有「授权物化」这一步。
继承行为(有用的 workaround):给
D:\dsh补上可继承的(OI)(CI)(M,WO)后,其新建子目录自动继承该 ACE,可直接作为工作区使用,同样通过第 3 项的端到端验证。影响
Authenticated Users: Modify继承而来,标准用户拿不到WRITE_OWNER。workspace-write的设计意图正好相反。Win32 5,与真实原因(缺少WRITE_OWNER)之间没有任何提示。建议
1. 让报错可操作(最小改动,收益最大)
在
grantWrite失败且错误为ERROR_ACCESS_DENIED时,说明原因并给出一次性修复命令,例如:2. 选定工作区时预检
在物化授权前检查(owner 是否为当前用户、是否存在有效的
WRITE_OWNER),在用户选择工作区时就告警,而不是等到第一条命令失败、且只报一个 Win32 码。3. 补文档
把该前提写进用户可见的文档(
dsh-sandbox/dsh-pwsh-sandbox/dsh-base/dsh-sandbox-policy的 README),而不只是后端包 README 的 "Verified boundaries"。4. 可选的自愈(须用户显式确认)
调用者已是所有者(隐式
WRITE_DAC),因此有能力改写自己的 DACL——而后端本来就在做 DACL 变更(能力 ACE +FILE_DELETE_CHILD拒绝项)。可在首次遇到该错误时询问用户是否允许为 owner 补一条WRITE_OWNER。注意这会改变目录的安全语义(允许该用户取得所有权),因此应当显式选择加入,不适合默认静默执行。
附:相关文件位置
packages/sandbox/sandbox-windows-acl/src/acl.tsmergeAndApply:合并 DACL + 标签的单次SetNamedSecurityInfoWpackages/sandbox/sandbox-windows-acl/README.mdL122.../README.zh.mdL122WRITE_OWNERpackages/sandbox/sandbox/README.mdL12SANDBOX_UNAVAILABLE失败,绝不不受限运行All reactions