You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug] Windows ACL 沙箱:Low 完整性标签只落在"授权后新建"的子项,已存在的子目录永远被拒写;Windows ACL sandbox: the Low integrity label only reaches children created after the grant, so pre-existing subdirectories stay unwritable
#8560
Symptom. On Windows with the official desktop build (0.2.0-rc.2), writes into subdirectories of an existing workspace fail with Access denied, while writing into the workspace root succeeds. Reads and listings work. The condition recurs: after a manual repair the workspace is fully writable, then reverts.
This is not a missing capability ACE. Byte-wise SDDL comparison of a writable and a non-writable subdirectory shows the S-1-4-… write ACE (0x110156) present and inherited in both. The only difference is the mandatory integrity label:
writable: Mandatory Label\Low Mandatory Level:(OI)(CI)(NW)
not writable: (no label)
Mechanism.grantWrite in @deepseek-ai/dsh-sandbox-windows-acl applies three edits per grant: the capability-SID allow ACE, a Deny for FILE_DELETE_CHILD, and a Low no-write-up mandatory label, documented as "inheriting to subcontainers and objects so later children carry the same label." The first two inherit through the DACL; the label only reliably reaches children created after the grant. Because the sandboxed process runs at Low integrity, Windows' no-write-up check then denies writes into unlabeled directories — regardless of their permissions.
Repro / verification.
icacls "<dir>" → no Mandatory Label, write denied.
icacls "<dir>" /setintegritylevel (OI)(CI)Low → the same directory becomes writable immediately.
Later (after DSH granted again for another existing session) the count reverted to 5/17, exactly the directories that had lost the label. Reproduced twice.
diagnose-windows-sandbox-acl.ps1 classifies this as PRECONDITION and repairs the DACL only, so it cannot fix it — the missing piece is not a permission entry.
Suggested fix. Have grantWrite explicitly re-apply the label across the existing subtree (the current "skip the eager full-tree re-propagation when the label is present" optimization leaves already-unlabeled children permanently broken), or accept an inheritable label on the parent in the write check; at minimum, warn when a granted directory's children lack the label. An official dsh sandbox repair --workspace <path> entry point would help users recover.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
环境
0.2.0-rc.2profile = desktopD:\dsh-agent(已使用约一个月,根目录下已有 17 个子文件夹)@deepseek-ai/dsh-sandbox-windows-acl/dsh-sandbox-policy现象
D:\dsh-agent\下新建文件成功。Access denied,例如:D:\dsh-agent\.temp\D:\dsh-agent\FGOBondApp\release\与 #401 / #423 的归因不同:capability ACE 一直在
#401 / #423 归因于「capability ACE 永不补授」。但逐字节对比 SDDL 后,能写与不能写的目录,那条写 ACE 实质完全相同:
0x110156即DeleteSubdirectoriesAndFiles, Write, Delete, Synchronize——两条都在,且都是ID(继承而来)。唯一的差别是强制性完整性标签。 这一点用"同一时刻、同一工作区、逐目录对照"得到 17/17 的完全对应:
.acl-repair-20261001、backups、docs、FGOBondApp、scratch.gradle-home、.npm-cache、.temp、.tmp、.tmp-engine、android-keys、baidu-player-backup-20260911-105257、data、plugins、scripts、symbols-elev、需要验证同一工作区、仍受沙箱限制时实测的被拒清单:
12 个对 12 个,逐一吻合;带标签的 5 个正是当时全部可写的那 5 个。
同一次测量中,这 17 个目录的写 ACE 逐条相同:
被拒的目录上那条 ACE 一条都不缺。
因果实验(充分性):给一个被拒的目录补上标签、不动 ACE →
必要性(因果):在沙箱生效的状态下,对同一个能写目录只改标签、完全不动权限条目:
docs的完整性标签Low Mandatory Level:(OI)(CI)(NW)Medium Mandatory Level:(OI)(CI)(NW)Low Mandatory Level:(OI)(CI)(NW)每一步都同步记录了该目录的写 ACE,前后逐字节一致:
同一条命令内还以"无标签目录"作阴性对照(
plugins/scripts/data始终被拒),用以确认测量环境确实处于沙箱之下、而不是脱离沙箱后的假阳性。结论:低完整性标签既充分(补上即可写)、又必要(改成 Medium 即被拒);而那条 capability ACE 在所有状态中始终存在且未变 —— 它不是判别因素。
机制(对照本包源码注释)
@deepseek-ai/dsh-sandbox-windows-acl中grantWrite的注释自述:每次授权在一次SetNamedSecurityInfoW里做三件事——FILE_DELETE_CHILDright from the world SIDbuildLowLabelAcl)而
buildLowLabelAcl的注释是:关键在 "later children":
S-1-4-…写 ACE);沙箱进程运行在低完整性(Low IL)下,Windows 的强制完整性检查(no-write-up)会拒绝它写入没有标签的对象。因此:
这也解释了另一个现象:
diagnose-windows-sandbox-acl.ps1对本例判定为PRECONDITION(它只写 DACL),补上 WRITE_OWNER 后依然不可写。复现与验证
第 4 步的两个观测点(同一工作区、同一 DSH 进程未重启):
带标签的 5 个全部可写,其余 12 个全部被拒——对应关系精确。
影响面
danger-full-access。建议的修法
grantWrite对已存在的子树做一次显式标签补授;关键在于当前的"标签已存在就跳过整树重传播"的优化,会让已经缺标签的子目录永远修不回来。注释里提到的
label skip the eager full-tree re-propagation正是这个优化的入口。grantWrite在检测到子目录缺标签时给出可诊断的告警/日志,而不是让用户只看到裸的Access denied。dsh sandbox repair --workspace <path>,一键重打标签并报告结果。备注
icacls输出为直接抓取,未做改写。English summary
Symptom. On Windows with the official desktop build (
0.2.0-rc.2), writes into subdirectories of an existing workspace fail withAccess denied, while writing into the workspace root succeeds. Reads and listings work. The condition recurs: after a manual repair the workspace is fully writable, then reverts.This is not a missing capability ACE. Byte-wise SDDL comparison of a writable and a non-writable subdirectory shows the
S-1-4-…write ACE (0x110156) present and inherited in both. The only difference is the mandatory integrity label:Mechanism.
grantWritein@deepseek-ai/dsh-sandbox-windows-aclapplies three edits per grant: the capability-SID allow ACE, a Deny forFILE_DELETE_CHILD, and a Low no-write-up mandatory label, documented as "inheriting to subcontainers and objects so later children carry the same label." The first two inherit through the DACL; the label only reliably reaches children created after the grant. Because the sandboxed process runs at Low integrity, Windows' no-write-up check then denies writes into unlabeled directories — regardless of their permissions.Repro / verification.
icacls "<dir>"→ noMandatory Label, write denied.icacls "<dir>" /setintegritylevel (OI)(CI)Low→ the same directory becomes writable immediately.icacls "<workspace>" /setintegritylevel (OI)(CI)Low /T /C /Q→ 17/17 top-level directories writable.diagnose-windows-sandbox-acl.ps1classifies this asPRECONDITIONand repairs the DACL only, so it cannot fix it — the missing piece is not a permission entry.Suggested fix. Have
grantWriteexplicitly re-apply the label across the existing subtree (the current "skip the eager full-tree re-propagation when the label is present" optimization leaves already-unlabeled children permanently broken), or accept an inheritable label on the parent in the write check; at minimum, warn when a granted directory's children lack the label. An officialdsh sandbox repair --workspace <path>entry point would help users recover.All reactions