fix(security): use jq for JSON construction in analyze_response()

Replace two heredocs that write analysis results with jq construction
to prevent JSON injection via work_summary or other string fields.

Fixed locations:
- Line 205-235: JSON parsing path analysis result
- Line 351-381: Text parsing path analysis result

Both now use jq with --arg for strings and --argjson for numeric/boolean
fields, ensuring proper escaping of special characters.
This commit is contained in:
frankbria 2026-01-08 21:10:33 -07:00
parent 50f6ef7a96
commit c7c6c9389d

View file

@ -201,26 +201,38 @@ analyze_response() {
fi
fi
# Write analysis results for JSON path
cat > "$analysis_result_file" << EOF
{
"loop_number": $loop_number,
"timestamp": "$(get_iso_timestamp)",
"output_file": "$output_file",
"output_format": "json",
"analysis": {
"has_completion_signal": $has_completion_signal,
"is_test_only": $is_test_only,
"is_stuck": $is_stuck,
"has_progress": $has_progress,
"files_modified": $files_modified,
"confidence_score": $confidence_score,
"exit_signal": $exit_signal,
"work_summary": "$work_summary",
"output_length": $output_length
}
}
EOF
# Write analysis results for JSON path using jq for safe construction
jq -n \
--argjson loop_number "$loop_number" \
--arg timestamp "$(get_iso_timestamp)" \
--arg output_file "$output_file" \
--arg output_format "json" \
--argjson has_completion_signal "$has_completion_signal" \
--argjson is_test_only "$is_test_only" \
--argjson is_stuck "$is_stuck" \
--argjson has_progress "$has_progress" \
--argjson files_modified "$files_modified" \
--argjson confidence_score "$confidence_score" \
--argjson exit_signal "$exit_signal" \
--arg work_summary "$work_summary" \
--argjson output_length "$output_length" \
'{
loop_number: $loop_number,
timestamp: $timestamp,
output_file: $output_file,
output_format: $output_format,
analysis: {
has_completion_signal: $has_completion_signal,
is_test_only: $is_test_only,
is_stuck: $is_stuck,
has_progress: $has_progress,
files_modified: $files_modified,
confidence_score: $confidence_score,
exit_signal: $exit_signal,
work_summary: $work_summary,
output_length: $output_length
}
}' > "$analysis_result_file"
rm -f ".json_parse_result"
return 0
fi
@ -335,26 +347,38 @@ EOF
exit_signal=true
fi
# Write analysis results to file (text parsing path)
cat > "$analysis_result_file" << EOF
{
"loop_number": $loop_number,
"timestamp": "$(get_iso_timestamp)",
"output_file": "$output_file",
"output_format": "text",
"analysis": {
"has_completion_signal": $has_completion_signal,
"is_test_only": $is_test_only,
"is_stuck": $is_stuck,
"has_progress": $has_progress,
"files_modified": $files_modified,
"confidence_score": $confidence_score,
"exit_signal": $exit_signal,
"work_summary": "$work_summary",
"output_length": $output_length
}
}
EOF
# Write analysis results to file (text parsing path) using jq for safe construction
jq -n \
--argjson loop_number "$loop_number" \
--arg timestamp "$(get_iso_timestamp)" \
--arg output_file "$output_file" \
--arg output_format "text" \
--argjson has_completion_signal "$has_completion_signal" \
--argjson is_test_only "$is_test_only" \
--argjson is_stuck "$is_stuck" \
--argjson has_progress "$has_progress" \
--argjson files_modified "$files_modified" \
--argjson confidence_score "$confidence_score" \
--argjson exit_signal "$exit_signal" \
--arg work_summary "$work_summary" \
--argjson output_length "$output_length" \
'{
loop_number: $loop_number,
timestamp: $timestamp,
output_file: $output_file,
output_format: $output_format,
analysis: {
has_completion_signal: $has_completion_signal,
is_test_only: $is_test_only,
is_stuck: $is_stuck,
has_progress: $has_progress,
files_modified: $files_modified,
confidence_score: $confidence_score,
exit_signal: $exit_signal,
work_summary: $work_summary,
output_length: $output_length
}
}' > "$analysis_result_file"
# Always return 0 (success) - callers should check the JSON result file
# Returning non-zero would cause issues with set -e and test frameworks