Skip to content

Commit a29d0d8

Browse files
la14-1louisgvclaude
authored
fix(security): replace variable-stored shell code with named function in verify.sh (#3073)
Fixes #3070 The port_check / port_check_r variables stored executable shell code as strings and expanded them via ${port_check} inside cloud_exec commands. This is an eval-equivalent pattern: if any part of the variable were ever derived from dynamic input, it would be directly exploitable as command injection. Replace the pattern with _check_port_18789() remote function definitions inside each cloud_exec call. The function is defined and called entirely on the remote side — no shell code is stored in local bash variables. Affected functions: - _openclaw_ensure_gateway (2 usages) - _openclaw_restart_gateway (1 usage) - _openclaw_verify_gateway_resilience (3 usages) Agent: security-auditor Co-authored-by: B <6723574+louisgv@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 4db068d commit a29d0d8

1 file changed

Lines changed: 14 additions & 10 deletions

File tree

sh/e2e/lib/verify.sh

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -168,19 +168,20 @@ input_test_codex() {
168168
_openclaw_ensure_gateway() {
169169
local app="$1"
170170
log_step "Ensuring openclaw gateway is running on :18789..."
171-
# Port check: ss works on all modern Linux; /dev/tcp works on macOS/some bash.
171+
# Port check is defined as a remote function — never stored as shell code in a local variable.
172+
# ss works on all modern Linux; /dev/tcp works on macOS/some bash.
172173
# Debian/Ubuntu bash is compiled WITHOUT /dev/tcp support, so ss must come first.
173-
local port_check='ss -tln 2>/dev/null | grep -q ":18789 " || (echo >/dev/tcp/127.0.0.1/18789) 2>/dev/null || nc -z 127.0.0.1 18789 2>/dev/null'
174174
cloud_exec "${app}" "source ~/.spawnrc 2>/dev/null; source ~/.bashrc 2>/dev/null; \
175175
export PATH=\$HOME/.npm-global/bin:\$HOME/.bun/bin:\$HOME/.local/bin:/usr/local/bin:\$PATH; \
176-
if ${port_check}; then \
176+
_check_port_18789() { ss -tln 2>/dev/null | grep -q ':18789 ' || (echo >/dev/tcp/127.0.0.1/18789) 2>/dev/null || nc -z 127.0.0.1 18789 2>/dev/null; }; \
177+
if _check_port_18789; then \
177178
echo 'Gateway already running'; \
178179
else \
179180
_oc_bin=\$(command -v openclaw) || exit 1; \
180181
if command -v setsid >/dev/null 2>&1; then setsid \"\$_oc_bin\" gateway > /tmp/openclaw-gateway.log 2>&1 < /dev/null & \
181182
else nohup \"\$_oc_bin\" gateway > /tmp/openclaw-gateway.log 2>&1 < /dev/null & fi; \
182183
elapsed=0; _gw_up=0; while [ \$elapsed -lt 180 ]; do \
183-
if ${port_check}; then echo 'Gateway started'; _gw_up=1; break; fi; \
184+
if _check_port_18789; then echo 'Gateway started'; _gw_up=1; break; fi; \
184185
sleep 1; elapsed=\$((elapsed + 1)); \
185186
done; \
186187
if [ \$_gw_up -eq 0 ]; then echo 'Gateway failed to start after 180s'; cat /tmp/openclaw-gateway.log 2>/dev/null; exit 1; fi; \
@@ -194,16 +195,16 @@ _openclaw_ensure_gateway() {
194195
_openclaw_restart_gateway() {
195196
local app="$1"
196197
log_step "Restarting openclaw gateway..."
197-
local port_check_r='ss -tln 2>/dev/null | grep -q ":18789 " || (echo >/dev/tcp/127.0.0.1/18789) 2>/dev/null || nc -z 127.0.0.1 18789 2>/dev/null'
198198
cloud_exec "${app}" "source ~/.spawnrc 2>/dev/null; source ~/.bashrc 2>/dev/null; \
199199
export PATH=\$HOME/.npm-global/bin:\$HOME/.bun/bin:\$HOME/.local/bin:/usr/local/bin:\$PATH; \
200+
_check_port_18789() { ss -tln 2>/dev/null | grep -q ':18789 ' || (echo >/dev/tcp/127.0.0.1/18789) 2>/dev/null || nc -z 127.0.0.1 18789 2>/dev/null; }; \
200201
_gw_pid=\$(lsof -ti tcp:18789 2>/dev/null || fuser 18789/tcp 2>/dev/null | tr -d ' ') && \
201202
kill \"\$_gw_pid\" 2>/dev/null; sleep 2; \
202203
_oc_bin=\$(command -v openclaw) || exit 1; \
203204
if command -v setsid >/dev/null 2>&1; then setsid \"\$_oc_bin\" gateway > /tmp/openclaw-gateway.log 2>&1 < /dev/null & \
204205
else nohup \"\$_oc_bin\" gateway > /tmp/openclaw-gateway.log 2>&1 < /dev/null & fi; \
205206
elapsed=0; _gw_up=0; while [ \$elapsed -lt 180 ]; do \
206-
if ${port_check_r}; then echo 'Gateway restarted'; _gw_up=1; break; fi; \
207+
if _check_port_18789; then echo 'Gateway restarted'; _gw_up=1; break; fi; \
207208
sleep 1; elapsed=\$((elapsed + 1)); \
208209
done; \
209210
if [ \$_gw_up -eq 0 ]; then echo 'Gateway restart failed after 180s'; cat /tmp/openclaw-gateway.log 2>/dev/null; exit 1; fi" >/dev/null 2>&1
@@ -496,13 +497,13 @@ verify_openclaw() {
496497
# ---------------------------------------------------------------------------
497498
_openclaw_verify_gateway_resilience() {
498499
local app="$1"
499-
local port_check='ss -tln 2>/dev/null | grep -q ":18789 " || (echo >/dev/tcp/127.0.0.1/18789) 2>/dev/null || nc -z 127.0.0.1 18789 2>/dev/null'
500500

501501
# Step 1: Confirm gateway is currently running
502502
log_step "Gateway resilience: checking gateway is running..."
503503
if ! cloud_exec "${app}" "source ~/.spawnrc 2>/dev/null; \
504504
export PATH=\$HOME/.npm-global/bin:\$HOME/.bun/bin:\$HOME/.local/bin:/usr/local/bin:\$PATH; \
505-
${port_check}" >/dev/null 2>&1; then
505+
_check_port_18789() { ss -tln 2>/dev/null | grep -q ':18789 ' || (echo >/dev/tcp/127.0.0.1/18789) 2>/dev/null || nc -z 127.0.0.1 18789 2>/dev/null; }; \
506+
_check_port_18789" >/dev/null 2>&1; then
506507
log_warn "Gateway not running — skipping resilience test"
507508
return 0
508509
fi
@@ -519,7 +520,9 @@ _openclaw_verify_gateway_resilience() {
519520
sleep 2
520521

521522
# Confirm it's actually down
522-
if cloud_exec "${app}" "${port_check}" >/dev/null 2>&1; then
523+
if cloud_exec "${app}" "\
524+
_check_port_18789() { ss -tln 2>/dev/null | grep -q ':18789 ' || (echo >/dev/tcp/127.0.0.1/18789) 2>/dev/null || nc -z 127.0.0.1 18789 2>/dev/null; }; \
525+
_check_port_18789" >/dev/null 2>&1; then
523526
log_warn "Gateway resilience: port still open after kill — process may not have died"
524527
else
525528
log_ok "Gateway resilience: gateway confirmed dead"
@@ -535,8 +538,9 @@ _openclaw_verify_gateway_resilience() {
535538
local recovered
536539
recovered=$(cloud_exec "${app}" "source ~/.spawnrc 2>/dev/null; \
537540
export PATH=\$HOME/.npm-global/bin:\$HOME/.bun/bin:\$HOME/.local/bin:/usr/local/bin:\$PATH; \
541+
_check_port_18789() { ss -tln 2>/dev/null | grep -q ':18789 ' || (echo >/dev/tcp/127.0.0.1/18789) 2>/dev/null || nc -z 127.0.0.1 18789 2>/dev/null; }; \
538542
elapsed=0; while [ \$elapsed -lt 60 ]; do \
539-
if ${port_check}; then echo 'recovered'; exit 0; fi; \
543+
if _check_port_18789; then echo 'recovered'; exit 0; fi; \
540544
sleep 1; elapsed=\$((elapsed + 1)); \
541545
done; echo 'timeout'" 2>&1) || true
542546

0 commit comments

Comments
 (0)