Skip to content

Commit 0a77d92

Browse files
orybandclaude
andcommitted
fix: propagate bash -c recursion failures to prevent silent approval
When recursive parse_compound for bash -c inner commands fails, the failed segment was silently dropped, potentially auto-approving compounds with unparseable inner scripts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent da37567 commit 0a77d92

2 files changed

Lines changed: 14 additions & 1 deletion

File tree

approve-compound-bash.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,11 @@ parse_compound() {
205205
# Recursively expand bash -c / sh -c
206206
if [[ "$line" =~ ^(env[[:space:]]+)?(/[^[:space:]]*/)?((ba)?sh)[[:space:]]+-c[[:space:]]*[\'\"](.*)[\'\"]$ ]]; then
207207
debug "Recursing into shell -c: ${BASH_REMATCH[5]}"
208-
parse_compound "${BASH_REMATCH[5]}"
208+
if ! parse_compound "${BASH_REMATCH[5]}"; then
209+
# Inner parse failed — emit wrapper as-is so it gets checked
210+
# against allow/deny lists (and likely falls through)
211+
printf '%s\0' "$line"
212+
fi
209213
else
210214
printf '%s\0' "$line"
211215
fi

test/security.bats

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,15 @@ load test_helper
133133
assert_denied
134134
}
135135

136+
# -- bash -c recursion failure must not silently approve --
137+
138+
@test "sec: bash -c with unparseable inner command falls through" {
139+
# If inner parse fails and the segment is silently dropped, only 'ls' remains
140+
# and would be approved. The fix emits the wrapper as-is, which is not allowed.
141+
run_hook "bash -c '<<<invalid syntax>>>' && ls" '["Bash(ls *)"]'
142+
assert_fallthrough
143+
}
144+
136145
# -- eval / source --
137146

138147
@test "sec: eval with dangerous command falls through (not in allow list)" {

0 commit comments

Comments
 (0)