fix(ssh): reject hostnames with stray leading or trailing colons in parseSshTarget - #93887
Conversation
…arseSshTarget
parseSshTarget would previously return host values like "host:" or ":22"
when the input had a trailing colon with no port, or a leading colon with
no host. These values flow directly into SSH config HostName fields and the
ssh CLI argv, which causes connections to fail.
Add a guard that rejects host parts starting or ending with ":" before
the existing "-" prefix check. Existing valid inputs ("host", "host:22",
"user@host:22") are unaffected.
Co-Authored-By: Claude <noreply@anthropic.com>
|
Codex review: needs maintainer review before merge. Reviewed June 20, 2026, 11:07 PM ET / 03:07 UTC. Summary PR surface: Source +5, Tests +11. Total +16 across 2 files. Reproducibility: yes. Current main source shows Review metrics: none identified. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Next step before merge
Security Review detailsBest possible solution: Land the shared parser-boundary validation with its regression coverage, keeping malformed SSH targets rejected before SSH config or argv construction. Do we have a high-confidence way to reproduce the issue? Yes. Current main source shows Is this the best way to solve the issue? Yes. The parser is the shared validation boundary for sandbox SSH config generation, gateway status tunnel startup, and discovery filtering, so one guard there is narrower and cleaner than adding caller-specific rejection. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against fce586538a50. Label changesLabel justifications:
Evidence reviewedPR surface: Source +5, Tests +11. Total +16 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
…arseSshTarget (openclaw#93887) * fix(ssh): reject hostnames with stray leading or trailing colons in parseSshTarget parseSshTarget would previously return host values like "host:" or ":22" when the input had a trailing colon with no port, or a leading colon with no host. These values flow directly into SSH config HostName fields and the ssh CLI argv, which causes connections to fail. Add a guard that rejects host parts starting or ending with ":" before the existing "-" prefix check. Existing valid inputs ("host", "host:22", "user@host:22") are unaffected. Co-Authored-By: Claude <noreply@anthropic.com> * fix(ssh): validate stray-colon host in explicit-port parse branch --------- Co-authored-by: Claude <noreply@anthropic.com>
Summary
parseSshTargetcurrently returns ahostfield that still contains a stray colon when the input has a trailing colon or a leading colon (e.g."host:",":22","user@host:"). The value flows directly into generated SSH config files (seesrc/agents/sandbox/ssh.ts:537) and thesshCLI argv, which causes the resulting connection to fail with an invalidHostName.This patch adds a guard that rejects any
hostpart that starts or ends with:. Existing valid inputs ("host","host:22","user@host:22") keep working.Linked context
N/A (no existing issue)
Real behavior proof
Behavior or issue addressed:
parseSshTargetreturned{ host: "host:", port: 22 }for input"host:"instead of rejecting it as invalid.Real environment tested: Node 22.19, Linux x86_64, local checkout of openclaw/openclaw main (bfc5e49), TypeScript source executed directly via tsx.
Exact steps or command run after this patch:
Script imports
parseSshTargetfrom the patched source and runs 7 inputs covering regressions and edge cases.Evidence after fix: Terminal capture of
noderuntime verification (copied live output):Observed result after fix: All 4 previously-broken inputs now correctly return
null; all 3 previously-valid inputs continue to return correct parsed objects.What was not tested: End-to-end SSH tunnel creation with these edge-case inputs (covered by the null rejection + existing callers already null-check
parseSshTargetresult before using).Tests and validation
Risk checklist