fix(agent): verify DACL and owner of package manager binaries before elevated execution - #1889
Conversation
Extract the owner/DACL verification logic from the policy file check into reusable helpers so the same admin-only-writability validation can be applied to other security-sensitive files: - verify_admin_only_writable(file, subject) with subject-aware errors - verify_admin_only_writable_path(path, subject), fail-closed on open - verify_elevated_executable_security(path, requires_elevation), a no-op unless the executable is about to run elevated Issue: DGW-434 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…elevated execution Before running a package-manager executable with an elevated (SYSTEM) token, verify that the binary is owned by SYSTEM or built-in Administrators and that its DACL does not grant write access to non-admin users. This prevents privilege escalation where a standard user plants or overwrites a package-manager binary (e.g. via a user-writable PATH entry) and gets it executed with elevated rights. The check is enforced at every elevated executable resolution point: - resolve_executable / create_process for directly spawned binaries (dotnet.exe, trusted PowerShell hosts) - resolve_winget_executable and resolve_trusted_chocolatey_executable, whose binaries are embedded into generated batch scripts and never reach create_process as the resolved executable Non-elevated (per-user) executions are unaffected, keeping user-scope installs (pip venvs, ~/.cargo, ~/.bun, etc.) working as before. Issue: DGW-434 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Let maintainers know that an action is required on their side
|
|
Implementation notes:
|
There was a problem hiding this comment.
Pull request overview
Adds security validation for package-manager executables before elevated Windows execution.
Changes:
- Generalizes file owner/DACL validation.
- Applies validation to direct and script-embedded executables.
- Adds elevated/non-elevated ACL tests.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
policy_security.rs |
Generalizes security verification. |
broker/mod.rs |
Exposes the security module internally. |
windows/process.rs |
Validates resolved executables. |
windows/mod.rs |
Propagates elevation state and validates WinGet/Chocolatey paths. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| pub(crate) fn verify_admin_only_writable_path(path: &Path, subject: &str) -> anyhow::Result<()> { | ||
| let file = File::open(path).with_context(|| format!("failed to open {subject} at {}", path.display()))?; | ||
| verify_admin_only_writable(&file, subject) |
| pub(crate) fn verify_elevated_executable_security(path: &Path, requires_elevation: bool) -> anyhow::Result<()> { | ||
| if !requires_elevation { | ||
| return Ok(()); | ||
| } | ||
|
|
||
| let subject = format!("elevated package-manager executable '{}'", path.display()); | ||
| verify_admin_only_writable_path(path, &subject) |
Before running a package-manager executable with an elevated (SYSTEM) token, the Agent package broker now verifies that the binary is owned by SYSTEM or the built-in Administrators group and that its DACL does not grant write access to non-admin users. Without this check, a standard user could plant or overwrite a package-manager binary (for example via a user-writable PATH entry) and have it executed with elevated rights, resulting in local privilege escalation.
The verification is fail-closed and enforced at every elevated executable resolution point: directly spawned binaries (dotnet.exe, trusted PowerShell hosts) as well as winget and Chocolatey binaries that are embedded into generated batch scripts. Non-elevated per-user executions are unaffected, so user-scope installs (pip virtualenvs, ~/.cargo, ~/.bun, and so on) keep working as before.
Issue: DGW-434