-
Notifications
You must be signed in to change notification settings - Fork 6
fix: restrict /proc/self/environ and docker-compose.yml secret exposure #621
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
Co-authored-by: Mossaka <5447827+Mossaka@users.noreply.github.com>
Co-authored-by: Mossaka <5447827+Mossaka@users.noreply.github.com>
|
📰 DEVELOPING STORY: Smoke Copilot reports failed. Our correspondents are investigating the incident... |
|
Chroot tests failed Smoke Chroot failed - See logs for details. |
|
💫 TO BE CONTINUED... Smoke Claude failed! Our hero faces unexpected challenges... |
✅ Coverage Check PassedOverall Coverage
📁 Per-file Coverage Changes (1 files)
Coverage comparison generated by |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request implements defense-in-depth mitigations for two secret exposure vectors that bypass the LD_PRELOAD one-shot token library: direct reads of /proc/self/environ and reads of the generated docker-compose.yml file via the /host mount.
Changes:
- Adds environment variable scrubbing in
entrypoint.shbeforeexecto clean/proc/self/environof sensitive tokens in both chroot and non-chroot execution paths - Adds
redactComposeSecrets()function to replace sensitive environment values with**REDACTED**indocker-compose.ymlimmediately afterdocker compose upcompletes - Adds 9 unit tests covering redaction behavior, edge cases, and token list verification
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/docker-manager.ts | Added SENSITIVE_ENV_NAMES constant and redactComposeSecrets() function to redact secrets from docker-compose.yml; integrated redaction after container startup |
| src/docker-manager.test.ts | Added comprehensive test suite (9 tests) for redactComposeSecrets() and SENSITIVE_ENV_NAMES validation |
| containers/agent/entrypoint.sh | Added DEFAULT_SENSITIVE_TOKENS constant and environment scrubbing logic before exec in both chroot and non-chroot paths to prevent /proc/self/environ exposure |
| containers/agent/one-shot-token/README.md | Updated documentation to note that /proc/self/environ direct reads are now mitigated by AWF's entrypoint scrubbing |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (env && typeof env === 'object') { | ||
| for (const key of Object.keys(env)) { | ||
| if (SENSITIVE_ENV_NAMES.has(key) && env[key]) { | ||
| env[key] = '**REDACTED**'; | ||
| redacted = true; | ||
| } | ||
| } | ||
| } |
Copilot
AI
Feb 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The environment type check could be more specific to avoid silent failures. Docker Compose supports both object format (environment: {KEY: value}) and array format (environment: [KEY=value]). While this codebase only generates object format, a more defensive check would be if (env && typeof env === 'object' && !Array.isArray(env)) to explicitly skip array-formatted environments rather than silently processing them incorrectly. Currently, if env is an array, Object.keys(env) would return string indices ("0", "1", etc.) which wouldn't match SENSITIVE_ENV_NAMES, causing the redaction to silently skip those entries.
- Remove shell-level `unset` of sensitive tokens from entrypoint.sh. The shell unset ran before exec, so tokens were gone from the environment before the one-shot-token library could cache them, breaking authentication (Copilot CLI could not find tokens). - Add __attribute__((constructor)) to one-shot-token.c that eagerly caches all sensitive token values and calls unsetenv() at library load time (before main()). This closes the /proc/self/environ exposure window without breaking getenv() access. - Write docker-compose.yml with mode 0600 to prevent the agent container (running as awfuser) from reading secrets via /host mount. This eliminates the TOCTOU race between container start and redaction. - Fix CodeQL TOCTOU alert in redactComposeSecrets by replacing existsSync+readFileSync with a single readFileSync in try/catch. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Security Review & FixesReviewed this PR and addressed the following issues: Issues Found & Fixed (in cf5fff4)1. Shell-level Fix: Removed the shell-level unset and moved 2. CodeQL TOCTOU race in Fix: Replaced with a single 3. docker-compose.yml readable by agent container (Security) Fix: Write Also merged
|
|
📰 DEVELOPING STORY: Smoke Copilot reports failed. Our correspondents are investigating the incident... |
|
Chroot tests failed Smoke Chroot failed - See logs for details. |
|
💫 TO BE CONTINUED... Smoke Claude failed! Our hero faces unexpected challenges... |
|
🌑 The shadows whisper... Smoke Codex failed. The oracle requires further meditation... |
❌ Build Test: Java - FAILEDStatus: Unable to execute tests due to environment issues. IssueJava/Maven commands cannot be executed in the current AWF agent environment (chroot mode). All Java commands return bash version information instead of executing: Environment Details
Test Results
Overall: FAILED - Cannot execute Java/Maven commands RecommendationThis test should be run in a standard GitHub Actions environment with the
|
Two paths bypass the
LD_PRELOADone-shot token library to leak secrets: reading/proc/self/environdirectly, and reading the generateddocker-compose.ymlvia the/hostmount./proc/self/environscrubbingSensitive env vars are
unsetinentrypoint.shbeforeexec, so the new process image's/proc/self/environis clean. Applied in both chroot and non-chroot paths. Default token list extracted toDEFAULT_SENSITIVE_TOKENSconstant; overridable viaAWF_ONE_SHOT_TOKENS.docker-compose.ymlredactionredactComposeSecrets()replaces sensitive values with**REDACTED**immediately afterdocker compose upreturns. The file has already been consumed—redaction is purely to close the read window from inside the container.SENSITIVE_ENV_NAMESin TypeScript andDEFAULT_SENSITIVE_TOKENSin shell are aligned and includeGITHUB_PERSONAL_ACCESS_TOKEN(not in the C library defaults but passed by the CLI)redactComposeSecrets()Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.