From 4da72974d5067171ab3e00ec9a083e35590131be Mon Sep 17 00:00:00 2001 From: shujaat hasan Date: Fri, 26 Jun 2026 14:40:57 +0200 Subject: [PATCH] fix: validate COSIGN_VERSION and enforce TLS 1.2 on installer downloads Bugbot (promotion PR #113), two findings in scripts/install.sh: - Unvalidated cosign version in URL: COSIGN_VERSION (env-overridable) was interpolated into the Sigstore download URL without the semver/path-traversal gate applied to RELEASE_VERSION. Generalized validate_tag into validate_version_tag and apply it to COSIGN_VERSION before building the URL. (scripts/install.sh:45) - Signature download curls omit TLS: the .sig/.cert fetches (and the binary, SHA256SUMS, and latest-redirect curls) lacked --tlsv1.2, unlike the new cosign bootstrap fetches. Add --tlsv1.2 to every security-sensitive download. (scripts/install.sh:335) Co-Authored-By: Claude Opus 4.8 --- scripts/install.sh | 36 +++++++++++++++++++++++---------- scripts/tests/install-verify.sh | 16 +++++++++++++++ 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/scripts/install.sh b/scripts/install.sh index 8814dc4f..b76b8ba3 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -161,6 +161,12 @@ ensure_cosign() { *) return 1 ;; esac + # COSIGN_VERSION is env-overridable and gets interpolated into the Sigstore + # download URL, so it needs the same semver + path-traversal gate as the + # release tag — a crafted value must not redirect which release path we fetch. + validate_version_tag "$COSIGN_VERSION" "cosign version" \ + "Set COSIGN_VERSION to a published cosign release tag (e.g. v2.4.1)." + cbase="https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}" casset="cosign-${OS}-${cosign_arch}" cbin="$TMP/cosign" @@ -196,7 +202,7 @@ resolve_tag() { # Use the redirect-trail of /releases/latest to learn the tag — # avoids hitting the rate-limited /api/repos endpoint for the # zero-auth one-liner case. - redirect_url="$(curl -fsSI \ + redirect_url="$(curl -fsSI --tlsv1.2 \ "https://github.com/${GITHUB_REPO}/releases/latest" \ | awk '/^[Ll]ocation:/ { print $2 }' \ | tr -d '\r')" @@ -219,24 +225,32 @@ resolve_tag() { # most security-sensitive download in the installer. Constrain it to a release # tag shape and refuse any '/' or '..' (RFC-0001 R8, backend#889). Matches the # client bootstrap's gate (^v[0-9]+\.[0-9]+\.[0-9]+([.-][A-Za-z0-9.]+)?$). -validate_tag() { +# validate_version_tag