-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Bug
scripts/govern-shell.sh constructs the governance evaluation JSON using printf with an unescaped variable:
RESULT=$(printf '{"tool":"run_shell","action":"%s","path":"."}' "$COMMAND" | shellforge evaluate 2>/dev/null || echo '{"allowed":true}')Problem
If $COMMAND contains JSON special characters — double quotes, backslashes, newlines, or control characters — the resulting JSON is malformed. Examples:
| Command | Output |
|---|---|
echo "hello" |
{"tool":"run_shell","action":"echo "hello"","path":"."} ← invalid JSON |
sed 's/foo/bar/' |
breaks shellforge evaluate JSON parsing |
printf "\n" |
embeds literal newline into JSON string |
Impact
When shellforge evaluate receives malformed JSON, it unmarshal-fails and (due to issue #62) defaults to allow. The || echo '{"allowed":true}' fallback also hides the error. Net result: governance check is silently bypassed for any command with quotes or backslashes — a very common case in shell usage.
Fix
Use jq to safely construct the JSON payload:
RESULT=$(jq -n --arg cmd "$COMMAND" '{"tool":"run_shell","action":$cmd,"path":"."}' | shellforge evaluate 2>/dev/null || echo '{"allowed":true}')Or use printf '%s' with a heredoc approach. At minimum, escape the command string before interpolation.
Related
- Issue bug: govern-shell.sh uses fragile sed to parse JSON — denial reason extraction can fail silently #67 — fragile
sedJSON parsing on the output side - Issue bug: cmdEvaluate silently ignores JSON unmarshal error — governance bypass #62 —
cmdEvaluateignores unmarshal errors, defaults to allow
Severity: Medium — governance bypass for any shell command containing quotes or backslashes, which is normal in real agent usage.