Skip to content

Conversation

@Claude
Copy link
Contributor

@Claude Claude AI commented Feb 10, 2026

Configuration files (docker-compose.yml, squid.conf, seccomp-profile.json) were being deleted during cleanup, making post-execution debugging impossible.

Changes

  • Preserve configuration files to /tmp/awf-configs-<timestamp>/ before deleting workDir
  • Log preservation location for visibility
  • Follows existing pattern used for agent and squid logs

Implementation

Added preservation logic in cleanup() before rmSync:

// Preserve configuration files before cleanup for debugging
const configDestination = path.join(os.tmpdir(), `awf-configs-${timestamp}`);
const configFiles = ['docker-compose.yml', 'squid.conf', 'seccomp-profile.json'];

for (const configFile of configFiles) {
  const configPath = path.join(workDir, configFile);
  if (fs.existsSync(configPath)) {
    if (!fs.existsSync(configDestination)) {
      fs.mkdirSync(configDestination, { recursive: true });
    }
    fs.copyFileSync(configPath, path.join(configDestination, configFile));
  }
}

Configuration files are now accessible for debugging after container execution completes.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/github/gh-aw-firewall/actions/jobs/63161757918/logs
    • Triggering command: /usr/bin/gh gh api repos/github/gh-aw-firewall/actions/jobs/63161757918/logs --paginate (http block)
  • https://api.github.com/repos/github/gh-aw-firewall/actions/runs/21880608782/artifacts
    • Triggering command: /usr/bin/gh gh run download 21880608782 --repo github/gh-aw-firewall --name agent-artifacts /home/REDACTED/.nvm/nvm.sh /home/REDACTED/.nvm/package.json /home/REDACTED/.nvm/rename_test.sh /home/REDACTED/.nvm/test (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
@Claude Claude AI changed the title [WIP] Fix failing GitHub Actions workflow agent fix: preserve docker-compose and config files during cleanup Feb 10, 2026
@Claude Claude AI requested a review from lpcox February 10, 2026 20:17
@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

💫 TO BE CONTINUED... Smoke Claude failed! Our hero faces unexpected challenges...

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

Chroot tests failed Smoke Chroot failed - See logs for details.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

📰 DEVELOPING STORY: Smoke Copilot reports failed. Our correspondents are investigating the incident...

@lpcox lpcox closed this Feb 10, 2026
@github-actions
Copy link
Contributor

⚠️ Security Issue: Credential Leakage in Preserved Configuration Files

This PR introduces a credential leakage vulnerability by preserving configuration files that contain sensitive information in plaintext.

Vulnerability Details

1. GitHub Tokens and API Keys in docker-compose.yml

Location: src/docker-manager.ts:1182-1206

Issue: The preserved docker-compose.yml contains the entire environment: object passed to the agent container, which includes sensitive credentials:

services:
  agent:
    environment:
      GITHUB_TOKEN: "ghp_xxxxxxxxxxxx"
      GH_TOKEN: "ghp_xxxxxxxxxxxx"
      GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_xxxxxxxxxxxx"
      ANTHROPIC_API_KEY: "sk-ant-xxxxxxxxxxxx"
      # ... potentially hundreds more with --env-all

Evidence from codebase (src/docker-manager.ts:138-153):

if (config.envAll) {
  for (const [key, value] of Object.entries(process.env)) {
    if (value !== undefined && !EXCLUDED_ENV_VARS.has(key) && !Object.prototype.hasOwnProperty.call(environment, key)) {
      environment[key] = value;
    }
  }
} else {
  // Default behavior: selectively pass through specific variables
  if (process.env.GITHUB_TOKEN) environment.GITHUB_TOKEN = process.env.GITHUB_TOKEN;
  if (process.env.GH_TOKEN) environment.GH_TOKEN = process.env.GH_TOKEN;
  if (process.env.GITHUB_PERSONAL_ACCESS_TOKEN) environment.GITHUB_PERSONAL_ACCESS_TOKEN = process.env.GITHUB_PERSONAL_ACCESS_TOKEN;
  if (process.env.ANTHROPIC_API_KEY) environment.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
  // ...
}

2. SSL Certificate Paths Exposed

Location: src/docker-manager.ts:1184 (preserves squid.conf)

Issue: When SSL Bump is enabled (--ssl-bump), squid.conf contains paths to SSL private keys:

cert=/tmp/awf-ssl-xxx/ca-cert.pem
key=/tmp/awf-ssl-xxx/ca-key.pem

While not the actual keys, this reveals infrastructure details about SSL certificate locations.

3. World-Readable Files in /tmp

Issue: Files written to /tmp/awf-configs-(timestamp)/ are created with default permissions, making them readable by any user on the system in multi-user environments (e.g., shared CI runners, development servers).

Attack Scenarios

  1. Multi-user CI/CD runners: Malicious users or compromised containers can read tokens from other jobs' preserved configs
  2. Shared development machines: Developers can access each other's credentials
  3. CI artifact collection: Automated systems might collect and upload /tmp contents, exposing tokens in logs/artifacts
  4. Post-exploitation: Attackers who gain limited access can escalate by harvesting preserved tokens

Impact Assessment

  • Severity: HIGH
  • Attack Complexity: LOW (just read a file in /tmp)
  • Scope: All users with --env-all, --env KEY=SECRET, or default token passthrough
  • Data at Risk: GitHub tokens (PATs, GITHUB_TOKEN), API keys (Anthropic, custom), SSL infrastructure details

Recommended Actions

Option 1: Remove the Feature (Safest)

Remove the configuration preservation code entirely. Users can already access configs during execution with --keep-containers.

Option 2: Redact Sensitive Data

If preservation is needed for debugging, apply the existing redactSecrets() function (src/redact-secrets.ts) to sanitize files before copying:

// Before copying docker-compose.yml
const dockerComposeContent = fs.readFileSync(configPath, 'utf-8');
const dockerComposeYaml = yaml.load(dockerComposeContent);

// Redact environment variables
if (dockerComposeYaml.services?.agent?.environment) {
  const env = dockerComposeYaml.services.agent.environment;
  for (const key of Object.keys(env)) {
    if (key.match(/TOKEN|SECRET|PASSWORD|KEY|AUTH/i)) {
      env[key] = '***REDACTED***';
    }
  }
}

// Write redacted version
fs.writeFileSync(
  path.join(configDestination, 'docker-compose.yml'),
  yaml.dump(dockerComposeYaml)
);

Option 3: Restrict Permissions

Set restrictive permissions on the preserved directory:

fs.mkdirSync(configDestination, { recursive: true, mode: 0o700 }); // Owner-only
fs.chmodSync(path.join(configDestination, configFile), 0o600); // Owner-only read/write

However, this doesn't prevent root/privileged processes from reading, and files may still leak via CI artifacts.

Conclusion

This PR weakens the security posture by creating a persistent credential leak vector. I recommend reverting this change and using the existing --keep-containers flag for debugging instead, which keeps configs in their original locations where they're already protected by the cleanup lifecycle.


Reference: The project already has credential redaction (src/redact-secrets.ts) for command logging. This same principle should apply to any persisted debugging artifacts.

AI generated by Security Guard

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