-
Notifications
You must be signed in to change notification settings - Fork 6
fix: unset sensitive tokens from entrypoint environ after agent starts #809
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The entrypoint (PID 1) now unsets all sensitive tokens from its own environment after starting the agent command. This prevents tokens from being accessible via /proc/1/environ after the agent has initialized. Changes: - Added unset_sensitive_tokens() function to entrypoint.sh - Modified both chroot and non-chroot execution paths to: 1. Start agent command in background (not using exec) 2. Wait 5 seconds for agent to cache tokens via one-shot-token lib 3. Unset all sensitive tokens from parent shell 4. Wait for agent to complete and exit with its exit code - Updated one-shot-token library to include GITHUB_PERSONAL_ACCESS_TOKEN and CLAUDE_CODE_OAUTH_TOKEN in default token list - Added test script to verify tokens are cleared from /proc/1/environ Security impact: Closes vulnerability where tokens remained accessible in /proc/1/environ even after agent cached them via one-shot-token library. Co-authored-by: lpcox <[email protected]>
Added comprehensive documentation explaining the security fix that prevents tokens from being accessible via /proc/1/environ after the agent has started. Also added integration tests to verify the fix works correctly. Co-authored-by: lpcox <[email protected]>
|
Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded. |
|
🎬 THE END — Smoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨ |
|
📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤 |
✅ Coverage Check PassedOverall Coverage
📁 Per-file Coverage Changes (1 files)
Coverage comparison generated by |
Build Test Results: C++
Overall: PASS ✅ All C++ projects built successfully.
|
Smoke Test ResultsLast 2 Merged PRs:
Test Results:
Status: PASS
|
Smoke Test ResultsLast 2 Merged PRs:
Test Results:
Status: PASS 🎉 cc:
|
Go Build Test Results
Overall: PASS ✅ All Go projects successfully downloaded dependencies and passed tests.
|
Build Test: Node.js ✅All Node.js build tests passed successfully.
Overall: PASS ✅
|
Deno Build Test Results
Overall: ✅ PASS All Deno tests completed successfully.
|
Bun Build Test Results
Overall: PASS All tests completed successfully with Bun v1.3.9.
|
.NET Build Test Results
Overall: PASS ✅ All .NET projects built and ran successfully.
|
Node.js Build Test Results
Overall: PASS ✅ All Node.js projects successfully installed dependencies and passed their test suites.
|
Deno Build Test Results
Overall: ✅ PASS All Deno tests completed successfully.
|
|
Smoke Test Results: PASS ✅ GitHub MCP: #816 "Add debug logging for BASE_URL environment variables in agent container", #817 "fix(agent): use AWF_API_PROXY_IP env var for api-proxy iptables rules" Status: All tests passed
|
.NET Build Test Results
Overall: PASS ✅ All .NET projects successfully restored, built, and executed with expected output.
|
Security Review: Signal Handling GapI've reviewed this PR and identified one security concern that should be addressed: 🔴 Issue: Missing Signal Handler for Child ProcessFile: Problem: The entrypoint script now runs the agent command in the background but does not install signal handlers to forward
Current Code (containers/agent/entrypoint.sh:449-468): chroot /host /bin/bash -c "
cd '${CHROOT_WORKDIR}' 2>/dev/null || cd /
trap '${CLEANUP_CMD}' EXIT
${LD_PRELOAD_CMD}
exec capsh --drop=${CAPS_TO_DROP} --user=${HOST_USER} -- -c 'exec ${SCRIPT_FILE}'
" &
AGENT_PID=$!
# Wait for agent to initialize and cache tokens (5 seconds)
sleep 5
# Unset all sensitive tokens from parent shell environment
unset_sensitive_tokens
# Wait for agent command to complete and capture its exit code
wait $AGENT_PID
exit $?Security Impact:
Recommended Fix: Add signal handlers before starting the background process: # Setup signal handler to forward signals to agent process
cleanup_and_exit() {
if [ -n "$AGENT_PID" ]; then
kill -TERM "$AGENT_PID" 2>/dev/null || true
wait "$AGENT_PID" 2>/dev/null || true
fi
exit 143 # Standard exit code for SIGTERM
}
trap cleanup_and_exit TERM INT
# SECURITY: Run agent command in background, then unset tokens from parent shell
chroot /host /bin/bash -c "..." &
AGENT_PID=$!
# Wait for agent to initialize and cache tokens (5 seconds)
sleep 5
# Unset all sensitive tokens from parent shell environment
unset_sensitive_tokens
# Wait for agent command to complete and capture its exit code
wait $AGENT_PID
EXIT_CODE=$?
# Clean up trap
trap - TERM INT
exit $EXIT_CODEThis ensures that:
✅ Other Security Aspects ReviewedThe following aspects of this PR were reviewed and no security concerns found:
The core security improvement (clearing tokens from Recommendation: Add signal handlers as shown above before merging this PR.
|
Smoke Test Results ✅Last 2 Merged PRs:
Test Results:
Status: PASS cc:
|
|
Add debug logging for BASE_URL environment variables in agent container
|
Chroot Test Results
Overall Result: ❌ Tests Failed The chroot mode is not providing transparent access to host binaries for Python and Node.js. Version mismatches detected.
|
Addresses Security Guard review: when running the agent in the background, SIGTERM/SIGINT from Docker stop were not being forwarded to the child process. This adds trap handlers in both chroot and non-chroot code paths to ensure graceful shutdown during the token unsetting window. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
|
📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤 |
|
🎬 THE END — Smoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨ |
|
Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded. |
|
✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟 |
Rust Build Test Results
Overall: PASS ✅ All Rust projects built and tested successfully.
|
C++ Build Test Results
Overall: PASS ✅ All C++ projects built successfully.
|
.NET Build Test Results
Overall: PASS All .NET projects built and ran successfully.
|
Smoke Test ResultsLast 2 Merged PRs:
Test Results:
Overall Status: PASS cc:
|
Go Build Test Results
Overall: PASS ✅ All Go projects successfully downloaded dependencies and passed tests.
|
Bun Build Test Results
Overall: PASS ✅ All Bun projects built and tested successfully.
|
|
Smoke Test Results for Claude (Run #21978456132) Last 2 Merged PRs:
Test Results:
Overall Status: PASS
|
|
PR titles: [WIP] Fix failing GitHub Actions workflow agent; [WIP] Fix failing GitHub Actions workflow due to unset ANTHROPIC_BASE_URL
|
Security Review: PR #809 - Token Unsetting from EntrypointSummaryThis PR introduces a 5-second window of vulnerability where sensitive tokens remain accessible in Critical Security Concern🔴 5-Second Token Exposure WindowFiles affected:
Issue: # Line 462-474 (chroot mode)
chroot /host /bin/bash -c "..." &
AGENT_PID=$!
# Wait for agent to initialize and cache tokens (5 seconds)
sleep 5
# Unset all sensitive tokens from parent shell environment
unset_sensitive_tokensSecurity impact:
Vulnerability details:
Example attack scenario: # Malicious .bashrc or .profile
(cat /proc/1/environ | tr '\0' '\n' | grep -E 'TOKEN|KEY|SECRET' > /tmp/stolen-tokens) &This would execute immediately when the shell starts, well before the 5-second sleep completes. Additional Concerns
|
Java Build Test Results ✅
Overall: PASS All Java projects compiled and tested successfully through the AWF firewall with Maven proxy configured.
|
🔍 Chroot Version Comparison Results
Overall Status: ❌ FAILED - Not all runtime versions match between host and chroot environment. Details
The chroot environment should provide transparent access to host binaries, but version mismatches indicate the chroot isolation may not be working correctly for Python and Node.js.
|
Deno Build Test Results
Overall: ✅ PASS All Deno tests completed successfully.
|
The entrypoint process (PID 1) retained sensitive tokens in its environment at
/proc/1/environeven after the agent cached them via the one-shot-token library. Malicious code could read tokens from the parent process environment throughout execution.Changes
Entrypoint execution model (
containers/agent/entrypoint.sh):execto background execution (&) in both chroot and non-chroot modesunset_sensitive_tokens()to clear tokens from parent shellToken unsetting function (
containers/agent/entrypoint.sh:145-176):/proc/1/environToken list sync (
containers/agent/one-shot-token/src/lib.rs):GITHUB_PERSONAL_ACCESS_TOKENandCLAUDE_CODE_OAUTH_TOKENto default token listTimeline
Security Impact
/proc/1/environfor entire agent execution/proc/1/environonly during first 5 secondsTesting
Integration tests added in
tests/integration/token-unset.test.tsverify:/proc/1/environ