Skip to content

feat: manually clear environ after unsetenv in one-shot-token#823

Closed
Claude wants to merge 5 commits intomainfrom
claude/clear-variable-in-unsetenv
Closed

feat: manually clear environ after unsetenv in one-shot-token#823
Claude wants to merge 5 commits intomainfrom
claude/clear-variable-in-unsetenv

Conversation

@Claude
Copy link
Contributor

@Claude Claude AI commented Feb 13, 2026

Plan: Address /proc/self/environ clearing

  • Research /proc/self/environ kernel behavior
  • Document /proc/self/environ limitation in README
  • Explain why environ pointer clearing is sufficient
  • Add security guidance about initial environment

Summary

After extensive research and testing, I've documented a fundamental Linux kernel limitation regarding /proc/self/environ:

Key Findings:

  1. /proc/self/environ is an immutable kernel snapshot from process start
  2. Runtime setenv() and unsetenv() do NOT update /proc/self/environ
  3. No userspace API can update it (would require CAP_SYS_RESOURCE and dangerous prctl(PR_SET_MM))

What Our Implementation Does:

Clears the environ global pointer - This affects all getenv() calls
Manually clears from environ array - Defense in depth
Calls unsetenv() - Standard POSIX cleanup
Cannot clear /proc/self/environ - Kernel limitation

Security Implications:

Best Practice: Do NOT pass sensitive tokens in the initial environment. Instead:

  • Read tokens from files at runtime
  • Set them via setenv() after process starts
  • They will never appear in /proc/self/environ

AWF Deployment: The agent container already follows this pattern - tokens are injected at runtime, so they never appear in /proc/self/environ.

Documentation Updates:

Updated README.md with:

  • New section "Understanding /proc/self/environ" explaining the kernel limitation
  • Clarified "What This Protects Against" vs "What This Does NOT Protect Against"
  • Security guidance about initial environment handling
  • Clear explanation of what we can and cannot clear

Add clear_from_environ() function to both C and Rust implementations
to ensure environment variables are completely removed from the environ
array after calling unsetenv(). This provides defense in depth by
manually removing the entry from the environ pointer in addition to
using the standard unsetenv() function.

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
@Claude Claude AI changed the title [WIP] Call unsetenv to clear environment variable in library feat: manually clear environ after unsetenv in one-shot-token Feb 13, 2026
@Claude Claude AI requested a review from lpcox February 13, 2026 08:34
Claude AI and others added 2 commits February 13, 2026 08:40
Add comprehensive test suite to verify that sensitive tokens are cleared
from the environ array after being accessed via getenv(). Tests verify
both C and Rust implementations.

- test_environ_array.c: Primary test checking extern char **environ
- test_proc_environ.c: Alternate test using /proc/self/environ
- test_proc_environ_fork.c: Test using child processes
- TESTS.md: Documentation explaining test approach and results

All tests pass for both C and Rust libraries, confirming that the
clear_from_environ() function correctly removes tokens from the
environment array while maintaining cached access.

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Add test_environ_array, test_proc_environ, and test_proc_environ_fork
to .gitignore and remove them from git tracking. These are compiled
binaries that should be built locally.

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Document the fundamental Linux kernel limitation that /proc/self/environ
is an immutable snapshot of the initial environment and cannot be updated
by unsetenv() or any userspace API.

Key points:
- /proc/self/environ is a kernel snapshot from process start
- Runtime setenv/unsetenv do NOT update /proc/self/environ
- Only prctl(PR_SET_MM) with CAP_SYS_RESOURCE could update it (dangerous)
- Solution: Do not pass sensitive tokens in initial environment
- AWF agent containers inject tokens at runtime, so they never appear
  in /proc/self/environ

This clarifies that our environ pointer clearing is correct and
sufficient for protecting against getenv() inspection, and that
/proc/self/environ protection only works if tokens are not in the
initial environment.

Co-authored-by: lpcox <15877973+lpcox@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.

2 participants