診斷 Windows 沙箱 ACL 失敗
用使用者能理解的語言,以純文字撰寫每次的授權請求。 提示訊息是使用者在放寬存取權限前唯一會閱讀的內容,因此必須獨立自足:說明腳本會觸及哪個資料夾、會為缺少權限的項目新增登入使用者的完全控制權限項目、會移除無關的封裝項目、檔案內容與擁有者保持不變、以及列印的復原指令能回復每項變更。請勿在請求中出現錯誤碼、WRITE_DAC/WRITE_OWNER、S-1-15-2-* SID、icacls、ACL、ACE、判斷結果名稱或開關:請寫成「Windows 檔案權限」,而非 ACL 或 ACE。僅需請求一次,對應一條指令。
一條指令同時診斷與修復
此腳本無模式切換。-Path、-AllowRoot 與 -Out 參數會讀取指定路徑及其所有上層目錄,並在單次執行中根據觀察到的問題進行修復:
- 路徑鏈上缺少有效
WRITE_DAC或WRITE_OWNER權限的目錄,會為登入使用者新增一筆「完全控制」允許 ACE,因為 DSH 若無這些權限將無法佈建其工作區授權。 - 明確的 AppContainer 封裝允許 ACE(
S-1-15-2-*,但不包括結尾為 1 或 2 的已知群組)會從其來源移除,以祖先目錄為優先,這也會移除這些封裝的存取權限。 - 若沙箱無法佈建的目錄(即其佈建錯誤報告中指出的工作區根目錄),或已授權的根目錄本身,也會在單次執行中搜尋其子樹中是否存在這些 ACE,因此無需為更深層的項目發起第二次請求。此有限範圍的掃描會報告
truncated(截斷)及無法讀取的目錄;若發生截斷,請將仍失敗的更深層路徑再傳入一次。
每次變更都會備份,然後透過重新讀取來驗證。-AllowRoot 參數限制所有操作範圍:只有當物件是該目錄或其嚴格內部子目錄時才會被變更,因此工作區根目錄可以自我修復。絕對不要將此拆分成診斷呼叫與修復呼叫,絕對不要為一次修復請求兩次批准,也絕對不要傳入不存在的模式開關。
& '<skill-directory>\scripts\diagnose-windows-sandbox-acl.ps1' -Path '<failing-path>' -AllowRoot '<authorized-directory>' -Out '<recovery-directory>'
exit $LASTEXITCODE
請替換為完整的、帶引號的路徑。保持 -Out 目錄持久存在且歸使用者所有,最好位於失敗的工作區旁;絕對不要使用技能資源目錄,因為該目錄會在技能卸載時被刪除。每次調用僅傳入一個路徑。
執行方法
在受限環境下重試失敗的操作。腳本會寫入權限,受限權杖無法執行此操作——若在沙箱內執行,它會將沙箱自身的限制誤報為缺少權限——因此請請求批准該指令,並在非受限(unconfined)環境下執行。在受限環境下執行此腳本永遠沒有用處。非受限執行不會提升 Windows 權杖層級。
診斷工作區寫入、列出目錄或顯然可讀取路徑的意外拒絕;對於預期中的拒絕則應說明原因:例如在工作區外寫入、在 read-only 唯讀目錄中寫入、管道化子行程 spawn EPERM、ConstrainedLanguage 錯誤等。如果批准被拒絕或無法取得,請將路徑報告為未診斷並停止。
讀取輸出
每筆記錄會輸出到 stdout、-Out 目錄下的 acl-report-*.jsonl 檔案,以及最終的 RECAP 行(該行包含判斷結果、變更、驗證、拒絕與掃描的摘要)。工具輸出只保留其結尾,因此請先閱讀摘要,若仍不足再從報告中讀取特定記錄。請相信 verification(驗證)記錄,而非 completed(已完成)動作。根據 details.nextAction 決定後續步驟:
nextAction | 含義 |
|---|---|
verify_original_confined_operation | 修復已驗證;請在受限環境下重試原始操作。 |
stop | 未修復任何項目,或執行因拒絕而終止。請報告並停止。 |
restore_pending_then_stop | 復原未經驗證。請依序執行列印的復原指令,然後停止。 |
拒絕 ACE 的存在本身並不代表因果關係,腳本也永遠不會移除拒絕 ACE;DSH 的 S-1-4-* 授權與 Everyone 的 DeleteSubdirectoriesAndFiles 拒絕是預期行為,並非衝突。若拒絕 ACE 阻止了修復,腳本會在嘗試復原其已進行的操作後結束執行(REPAIR_REFUSED 或 GRANT_FAILED)。每次變更會在 -Out 目錄中留下兩個檔案(acl-backup-<id>.json 及其對應的 .ps1 腳本),執行時會列印對應的 ROLLBACK 指令。
修復後及停止時
在受限環境下重試原始失敗的操作。已驗證的修復不應因為原始操作因其他原因失敗而被還原:請根據新的觀察結果繼續處理;若更深層的路徑仍遭到拒絕,請對該路徑再次執行同一條指令——同樣是一次呼叫、一次批准。
在任何修復失敗、被拒絕或驗證失敗後立即停止。 腳本已經還原了本次調用的變更;請勿重複執行或開始新的修復,也絕對不要手動移除拒絕 ACE。
停止的執行仍須向使用者提供決策資訊。 請說明是哪個物件以及缺少的權限或 ACE、哪些項目已變更且已復原、依序執行的復原指令,以及報告路徑。只有使用者可以解除限制,因此請要求他們暫時將此工作階段切換至完全存取(full access,簡體中文介面為「完全权限」),並說明這樣做會開放什麼:可以繼續在此模式下工作,或要求您繼續調查此檔案權限問題(因為報告中已記錄機制與證據)。然後請他們將此工作階段作為意見回饋送出,並引用相關的報告記錄,以便未處理的情境能送達我們——只有在此對話中提到的內容會隨之傳送。例如:
這個工作區被 Windows 檔案權限擋住了:
<物件>上<缺少的權限 / 違規的權限項目>。你可以把本工作階段切到「完全權限」(full access) 臨時繼續工作;切完之後既能直接幹活,也可以讓我繼續排查這個檔案權限問題(報告裡已經有機制和證據)。也麻煩把這個工作階段作為意見回饋發出去,好讓我們補上這個案例。This workspace is blocked by Windows file permissions:
<object><missing right / offending entry>. Switch this session to full access (完全权限) to keep working meanwhile; then either continue your work or have me keep investigating this file-permission problem from the report. Please also send this session as feedback so we can cover the case.
絕對不要
- 手動編輯 ACL、變更擁有者、清除拒絕 ACE,或遞迴取代子權限;
- 透過 UAC 或
runas以提升權限執行腳本; - 擴大
-AllowRoot的範圍以涵蓋至其祖先目錄,或重複執行已被拒絕或失敗的呼叫。
以使用者的語言報告:分析過的路徑、變更、驗證、復原指令、後續步驟。將已授權的非受限執行標記為「非受限執行」,而非「沙箱修復」。