-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Bug: Fragile sed-based JSON Parsing in govern-shell.sh
File: scripts/govern-shell.sh
Description
When a command is denied by governance, the script extracts the reason using sed:
REASON=$(echo "$RESULT" | sed 's/.*"reason":"\([^"]*\)".*/\1/')This has two failure modes:
-
Silent fallback: If the JSON doesn't contain a
"reason"field (e.g., the key is different, orshellforge evaluatereturns a different format),sedoutputs the entire raw JSON string unchanged. The error message shown to the user becomes the raw JSON blob. -
Regex failure on special characters: If
reasoncontains a forward slash/, backslash\, or other sed delimiter characters, the sed expression corrupts or truncates the output.
Reproduction
# If reason contains a slash:
echo '{"allowed":false,"reason":"Path not under outputs/dir"}' | sed 's/.*"reason":"\([^"]*\)".*/\1/'
# → "Path not under outputs" (truncated at the slash — BRE [^"]* stops at /)
# Actually [^"]* continues through /, this is OK. But still fragile.More critically: if shellforge evaluate fails and returns {"allowed":true} (the hardcoded fallback), but somehow the grep still fires, the sed parsing of an unrelated string gives garbage output.
Fix
Use python3 or jq for robust JSON parsing if available, with a safe fallback:
if command -v jq &>/dev/null; then
REASON=$(echo "$RESULT" | jq -r '.reason // "policy violation"')
else
REASON=$(echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('reason','policy violation'))" 2>/dev/null || echo "policy violation")
fiImpact
Users see confusing raw JSON in their terminal when a command is denied, instead of a clear human-readable reason.