From 777a37e02208d88dd76028cc592314d21b0dc971 Mon Sep 17 00:00:00 2001 From: Drew Newberry Date: Wed, 1 Apr 2026 09:49:59 -0700 Subject: [PATCH 1/2] fix(install): make checksum verification mandatory and validate redirect origin Checksum verification in install.sh previously had multiple silent bypass paths: missing sha256sum/shasum binary, missing checksums file download, and missing checksum entry. All three now produce hard errors instead of warnings. Additionally, validate the redirect URL from GitHub releases/latest against the expected github.com/NVIDIA/OpenShell origin to prevent MITM/DNS hijack attacks where an attacker could serve both a malicious binary and a matching checksums file. Closes #590 Closes #638 --- install.sh | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/install.sh b/install.sh index cf29ba746..26d42498f 100755 --- a/install.sh +++ b/install.sh @@ -161,6 +161,18 @@ resolve_version() { _latest_url="${GITHUB_URL}/releases/latest" _resolved="$(resolve_redirect "$_latest_url")" || error "failed to resolve latest release from ${_latest_url}" + # Validate that the redirect stayed on the expected GitHub origin. + # A MITM or DNS hijack could redirect to an attacker-controlled domain, + # which would also serve a matching checksums file (making checksum + # verification useless). See: https://github.com/NVIDIA/OpenShell/issues/638 + case "$_resolved" in + https://github.com/${REPO}/releases/*) + ;; + *) + error "unexpected redirect target: ${_resolved} (expected https://github.com/${REPO}/releases/...)" + ;; + esac + # Extract the tag from the resolved URL: .../releases/tag/v0.0.4 -> v0.0.4 _version="${_resolved##*/}" @@ -180,20 +192,20 @@ verify_checksum() { _vc_checksums="$2" _vc_filename="$3" + if ! has_cmd shasum && ! has_cmd sha256sum; then + error "neither 'shasum' nor 'sha256sum' found; cannot verify download integrity" + fi + _vc_expected="$(grep "$_vc_filename" "$_vc_checksums" | awk '{print $1}')" if [ -z "$_vc_expected" ]; then - warn "no checksum found for $_vc_filename, skipping verification" - return 0 + error "no checksum entry found for $_vc_filename in checksums file" fi if has_cmd shasum; then echo "$_vc_expected $_vc_archive" | shasum -a 256 -c --quiet 2>/dev/null elif has_cmd sha256sum; then echo "$_vc_expected $_vc_archive" | sha256sum -c --quiet 2>/dev/null - else - warn "sha256sum/shasum not found, skipping checksum verification" - return 0 fi } @@ -254,14 +266,13 @@ main() { error "failed to download ${_download_url}" fi - # Verify checksum + # Verify checksum (mandatory — never skip) info "verifying checksum..." - if download "$_checksums_url" "${_tmpdir}/checksums.txt"; then - if ! verify_checksum "${_tmpdir}/${_filename}" "${_tmpdir}/checksums.txt" "$_filename"; then - error "checksum verification failed for ${_filename}" - fi - else - warn "could not download checksums file, skipping verification" + if ! download "$_checksums_url" "${_tmpdir}/checksums.txt"; then + error "failed to download checksums file from ${_checksums_url}" + fi + if ! verify_checksum "${_tmpdir}/${_filename}" "${_tmpdir}/checksums.txt" "$_filename"; then + error "checksum verification failed for ${_filename}" fi # Extract From 42fb5d47ee0ef70170a6663bfea57b138918c40b Mon Sep 17 00:00:00 2001 From: Drew Newberry Date: Wed, 1 Apr 2026 09:54:22 -0700 Subject: [PATCH 2/2] fix(install): use fixed-string grep and limit redirect hops in downloads Use grep -F for checksum lookup to prevent regex metacharacters in filenames (e.g. dots) from matching unintended lines. Limit redirect hops to 5 in download() as defense-in-depth against redirect loops or redirect-based attacks. --- install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install.sh b/install.sh index 26d42498f..565c48c09 100755 --- a/install.sh +++ b/install.sh @@ -92,9 +92,9 @@ download() { _output="$2" if has_cmd curl; then - curl -fLsS --retry 3 -o "$_output" "$_url" + curl -fLsS --retry 3 --max-redirs 5 -o "$_output" "$_url" elif has_cmd wget; then - wget -q --tries=3 -O "$_output" "$_url" + wget -q --tries=3 --max-redirect=5 -O "$_output" "$_url" fi } @@ -196,7 +196,7 @@ verify_checksum() { error "neither 'shasum' nor 'sha256sum' found; cannot verify download integrity" fi - _vc_expected="$(grep "$_vc_filename" "$_vc_checksums" | awk '{print $1}')" + _vc_expected="$(grep -F "$_vc_filename" "$_vc_checksums" | awk '{print $1}')" if [ -z "$_vc_expected" ]; then error "no checksum entry found for $_vc_filename in checksums file"