From daa2f172621fd16847ce6d2683d7abd36572d93d Mon Sep 17 00:00:00 2001 From: luojiyin Date: Tue, 17 Feb 2026 16:49:38 +0800 Subject: [PATCH 1/2] Fix command injection vulnerability in tool_list_files by using array arguments --- lib/tools.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/tools.sh b/lib/tools.sh index f4082f4..d05a263 100644 --- a/lib/tools.sh +++ b/lib/tools.sh @@ -1203,9 +1203,9 @@ tool_list_files() { local count=0 if [[ "$recursive" == "true" ]]; then - local find_args="" + local find_args=() if [[ -n "$pattern" ]]; then - find_args="-name $pattern" + find_args=(-name "$pattern") fi local f local entries_ndjson="" @@ -1223,7 +1223,7 @@ tool_list_files() { entries_ndjson="${entries_ndjson}$(jq -nc --arg n "$rel" --arg t "$ftype" '{name: $n, type: $t}')"$'\n' count=$((count + 1)) done </dev/null | head -n "$TOOL_LIST_FILES_MAX") +$(find "$path" -maxdepth 10 "${find_args[@]}" 2>/dev/null | head -n "$TOOL_LIST_FILES_MAX") EOF if [[ -n "$entries_ndjson" ]]; then entries="$(printf '%s' "$entries_ndjson" | jq -s '.')" From 041527ee2d5f542c3d24b4e4850b64c4d4087879 Mon Sep 17 00:00:00 2001 From: luojiyin Date: Tue, 17 Feb 2026 17:23:04 +0800 Subject: [PATCH 2/2] Fix command injection vulnerability and improve exit code handling in tool_shell --- lib/tools.sh | 23 ++++++++++++++++++----- tests/test_tools.sh | 13 +++++++++---- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/lib/tools.sh b/lib/tools.sh index d05a263..d9caec8 100644 --- a/lib/tools.sh +++ b/lib/tools.sh @@ -744,10 +744,18 @@ tool_shell() { fi local output exit_code + local had_errexit=0 + if [[ "$-" == *e* ]]; then + had_errexit=1 + set +e + fi + if is_command_available timeout; then - output="$(timeout "$timeout_val" bash -c "$cmd" 2>&1)" || true + output="$(timeout "$timeout_val" bash -c "$cmd" 2>&1)" + exit_code=$? elif is_command_available gtimeout; then - output="$(gtimeout "$timeout_val" bash -c "$cmd" 2>&1)" || true + output="$(gtimeout "$timeout_val" bash -c "$cmd" 2>&1)" + exit_code=$? else # Pure-bash timeout fallback (macOS/Termux) local _tmpout @@ -761,15 +769,20 @@ tool_shell() { done if kill -0 "$_pid" 2>/dev/null; then kill -9 "$_pid" 2>/dev/null - wait "$_pid" 2>/dev/null || true + wait "$_pid" 2>/dev/null output="[command timed out after ${timeout_val}s]" + exit_code=124 else - wait "$_pid" 2>/dev/null || true + wait "$_pid" 2>/dev/null + exit_code=$? output="$(cat "$_tmpout")" fi rm -f "$_tmpout" fi - exit_code=$? + + if [[ "$had_errexit" -eq 1 ]]; then + set -e + fi # Truncate output to 100KB if [ "${#output}" -gt 102400 ]; then diff --git a/tests/test_tools.sh b/tests/test_tools.sh index e905d44..a807f9b 100755 --- a/tests/test_tools.sh +++ b/tests/test_tools.sh @@ -111,13 +111,10 @@ teardown_test_env test_start "tool_shell captures exit codes" setup_test_env -# Note: due to || true in shell execution, exit code capture may return 0 -# Test that the JSON is valid and contains exitCode field result="$(tool_shell '{"command":"exit 42"}')" assert_json_valid "$result" exit_code="$(printf '%s' "$result" | jq -r '.exitCode')" -# exitCode should be a number (may be 0 due to || true in implementation) -assert_match "$exit_code" '^[0-9]+$' +assert_eq "$exit_code" "42" teardown_test_env test_start "tool_shell blocks rm -rf /" @@ -138,6 +135,14 @@ result="$(tool_shell '{"command":"dd if=/dev/zero of=/dev/sda"}' 2>/dev/null)" | assert_contains "$result" "blocked" teardown_test_env +test_start "tool_shell returns timeout exit code" +setup_test_env +result="$(tool_shell '{"command":"sleep 2","timeout":1}' 2>/dev/null)" || true +assert_json_valid "$result" +exit_code="$(printf '%s' "$result" | jq -r '.exitCode')" +assert_eq "$exit_code" "124" +teardown_test_env + test_start "tool_shell allows safe commands" setup_test_env result="$(tool_shell '{"command":"date +%s"}')"