From 0370cc9818e9c488edc066eb9889a5973056cb0a Mon Sep 17 00:00:00 2001 From: cluade-reviewer-andresmgsl Date: Tue, 28 Jul 2026 16:18:33 +0000 Subject: [PATCH] fix: --version is refused at parse time, not at the 404 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codex's non-blocking nit, folded in by the maintainer's call now that the round is open anyway. The resolve-latest path validated what rig worked out for itself (""|*[!0-9.]*), and an explicit --version went straight into the download URL unchecked — so the value rig is HANDED, which is the one that reaches a URL path, was the only one nobody looked at. `--version ../../etc/passwd` was interpolated rather than refused. Not a trust boundary: this command is already root and the operator typed the flag. It is a diagnosis defect. A pin that cannot name a release should fail by name, next to the flag, rather than as an opaque 404 forty lines later. install.sh's valid_version is the same instinct. Four rows: two refusals, and two that reach "must run as root" — which is how a non-root suite proves a good pin got THROUGH validation rather than merely failing later. Mutation-checked: the refusals exit 1 instead of 2 without the guard. 756 passed (was 752), release 31, drill 43, shellcheck clean. --- commands/forgejo-runner-install.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/commands/forgejo-runner-install.sh b/commands/forgejo-runner-install.sh index 66d04dc..224e406 100755 --- a/commands/forgejo-runner-install.sh +++ b/commands/forgejo-runner-install.sh @@ -176,6 +176,19 @@ case "${INSTANCE#*://}" in */*[!/]*) die "--instance takes the instance ROOT, not a repository URL: got ${INSTANCE}. Scope comes from the token, not the URL." 2 ;; esac VERSION="${VERSION#v}" +# The same sane-version charset the resolve-latest path enforces further down. +# An explicit pin skipped it entirely and went straight into the download URL, +# so a value carrying `/` or `..` was interpolated into a URL PATH rather than +# refused. Not a trust boundary — this command is already root, and the operator +# typed the flag — but a pin that cannot name a release should fail BY NAME at +# parse time, not as an opaque 404 forty lines later. install.sh's +# valid_version is the same instinct, and the asymmetry was the whole defect: +# the value rig resolves for itself was checked, the one it is handed was not. +case "$VERSION" in + "") ;; # unset — the latest release is resolved and validated below + *[!0-9.]*|.*|*.) + die "--version must be a release number like 12.13.2 (got: ${VERSION})" 2 ;; +esac [ -n "$LABELS" ] || die "--labels must not be empty" 2 # The tenant user is the default when it is there: inside a ci-box the runner