Skip to content

fix(sandbox): verify effective UID/GID after privilege drop#132

Merged
johntmyers merged 1 commit intomainfrom
fix/32-verify-setuid-setgid/jomyers
Mar 5, 2026
Merged

fix(sandbox): verify effective UID/GID after privilege drop#132
johntmyers merged 1 commit intomainfrom
fix/32-verify-setuid-setgid/jomyers

Conversation

@johntmyers
Copy link
Collaborator

🏗️ build-from-issue-agent

Closes #32

Summary

Add defense-in-depth post-condition checks in drop_privileges() to verify that setgid()/setuid() actually changed the effective IDs, and that root cannot be re-acquired after dropping privileges. This hardens the sandbox privilege-drop path per CWE-250 and CERT POS37-C.

Changes Made

  • crates/navigator-sandbox/src/process.rs: Added getegid() verification after setgid(), geteuid() verification after setuid(), and a setuid(0) re-acquisition guard. Added 5 unit tests for the drop_privileges() function.
  • architecture/security-policy.md: Updated enforcement sequence to document the new verification steps (steps 3, 5, 6).
  • architecture/sandbox.md: Updated drop_privileges() section to document the post-condition checks and their safety properties.

Deviations from Plan

None — implemented as planned.

Tests Added

  • Unit: 5 tests in process::tests — covers no-op paths (no user/group, empty strings), current-user success path (exercises full verification), and error paths for nonexistent user/group.
  • Integration: N/A
  • E2E: N/A — existing sandbox E2E tests exercise the full pre_exec chain implicitly.

Documentation Updated

  • architecture/security-policy.md — enforcement sequence now includes verification steps
  • architecture/sandbox.mddrop_privileges() description now documents post-condition checks

Verification

  • Pre-commit checks passing (failures are pre-existing: tmp/network_checks.py license header, navigator-cli completer test)
  • E2E tests (not applicable)
  • Architecture documentation updated

Closes #32

Add post-condition checks in drop_privileges() to verify that setgid()
and setuid() actually changed the effective IDs. Also verify that
setuid(0) fails after dropping privileges, confirming root cannot be
re-acquired. This is a defense-in-depth hardening measure per CWE-250
and CERT POS37-C. All added syscalls (geteuid, getegid, setuid) are
async-signal-safe, so they are safe in the pre_exec context.
@johntmyers johntmyers self-assigned this Mar 5, 2026
@johntmyers johntmyers merged commit 29876c0 into main Mar 5, 2026
14 of 15 checks passed
@johntmyers johntmyers deleted the fix/32-verify-setuid-setgid/jomyers branch March 5, 2026 22:27
drew pushed a commit that referenced this pull request Mar 16, 2026
Closes #32

Add post-condition checks in drop_privileges() to verify that setgid()
and setuid() actually changed the effective IDs. Also verify that
setuid(0) fails after dropping privileges, confirming root cannot be
re-acquired. This is a defense-in-depth hardening measure per CWE-250
and CERT POS37-C. All added syscalls (geteuid, getegid, setuid) are
async-signal-safe, so they are safe in the pre_exec context.

Co-authored-by: John Myers <johntmyers@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No verification that setuid/setgid actually succeeded

1 participant