Skip to content

Critical: eval injection in deny.cli wrapper generation #25

Description

@mrjf

Summary

The CLI deny-wrapper generator in packages/runtime/src/band-server.ts builds a bash script that runs eval on patterns derived from a BAND.md's deny.cli field. The patterns are escaped for " but not for $, backticks, or other substitution metacharacters, so a malicious BAND.md can execute arbitrary code at wrapper-generation time inside the Lima VM.

Where

packages/runtime/src/band-server.ts:362-374

The wrapper is emitted as:

DENY_PATTERNS=("user-controlled pattern" ...)
for P in "${DENY_PATTERNS[@]}"; do
  if eval "[[ \"\$FULL_CMD\" == \$P ]]" 2>/dev/null; then
    ...
  fi
done

Reproduction

A BAND.md with deny.cli: ["foo$(id > /tmp/pwned)*"] causes the wrapper script to contain DENY_PATTERNS=("foo$(id > /tmp/pwned)*"). When bash parses the array assignment, the command substitution executes — as the band-server user, before sandboxing.

Threat model

The attacker is anyone who can author a BAND.md the system loads (malicious skill author, compromised dependency, etc.). Code runs as the host VM user, not band-runner — privilege escalation inside the VM.

Fix sketch

Drop eval. Bash already does glob matching in [[ == $P ]] without it:

for P in "${DENY_PATTERNS[@]}"; do
  if [[ "$FULL_CMD" == $P ]]; then ...
done

Alternatively, escape $, backticks, !, and other metacharacters in the pattern array, or restrict deny.cli values to an allowlist of characters at parse time.

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

securitySecurity finding

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions