fix(P16): aggregate.sh JSON injection + drift-gate fix (REQ-131, F11, F18)

---ci---
project: orca
phase: 16
milestone: v0.12
status: execute
---/ci---

orca-aggregate.sh: peer output validated via jq before JSON
interpolation (prevents injection from malicious peer). Peer name
escaped. Fallback: JSON shape validation via grep.
orca-pull.sh: R-020 drift gate now uses jq for accurate JSON parsing
(replaces fragile grep-based parsing). Fallback to grep if jq absent.
Build green.
This commit is contained in:
Jon Chery
2026-08-07 11:26:04 +00:00
parent c5ce851fc7
commit bfe92661ec
2 changed files with 33 additions and 4 deletions
+19 -1
View File
@@ -69,7 +69,25 @@ while IFS= read -r peer; do
orca_log_warn "aggregate" "$peer" "skipped" "failed to read state snapshot"
continue
fi
printf '{"peer":"%s","state":%s}\n' "$peer" "$snapshot" >>"$merge_tmp"
# REQ-131 / F11: use jq to safely construct JSON (prevents JSON
# injection from malicious peer output). $peer is sanitized; $snapshot
# is parsed as raw JSON by jq, so control chars can't break out.
if command -v jq >/dev/null 2>&1; then
snapshot_json="$(printf '%s' "$snapshot" | jq -c '.' 2>/dev/null)" || {
orca_log_warn "aggregate" "$peer" "skipped" "peer returned invalid JSON"
continue
}
peer_escaped="${peer//\"/\\\"}"
printf '{"peer":"%s","state":%s}\n' "$peer_escaped" "$snapshot_json" >>"$merge_tmp"
else
# Fallback: validate $snapshot looks like JSON before interpolation.
if ! printf '%s' "$snapshot" | grep -qE '^\s*\{.*\}\s*$'; then
orca_log_warn "aggregate" "$peer" "skipped" "peer returned non-JSON"
continue
fi
peer_escaped="${peer//\"/\\\"}"
printf '{"peer":"%s","state":%s}\n' "$peer_escaped" "$snapshot" >>"$merge_tmp"
fi
orca_log_info "aggregate" "$peer" "ok" "snapshot=$latest_json"
done < <(read_peers)