From 7898cfc1af333ef40920d954a2930c1dccc8f5a2 Mon Sep 17 00:00:00 2001 From: Giacomo Gorgellino Date: Tue, 16 Jun 2026 17:15:34 +0200 Subject: [PATCH 1/2] security: fail by default when no checksum found, add --no-verify flag Previously gri would print a warning and continue installing when a release published no checksum file. This is a silent security downgrade that the user never explicitly consented to. New behaviour: abort with an error if no checksum asset is found. The new --no-verify / -k flag opts out explicitly, making the intent visible and intentional rather than silent. Co-Authored-By: Claude Sonnet 4.6 (1M context) --- README.md | 4 ++++ gri | 17 ++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c81f75a..4160252 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ gri remove # remove an installed version |---|---| | `--user` / `-u` | Install in `~/.local/opt` and `~/.local/bin` (no sudo required) | | `--dry-run` / `-n` | Print what would happen without doing anything | +| `--allow-missing-checksum` / `-k` | Proceed even if the release provides no checksum file | Flags can appear anywhere in the command line and can be combined. @@ -89,6 +90,9 @@ sudo gri install yannh/kubeconform gri --user install gruntwork-io/terragrunt gri --user install yannh/kubeconform +# release with no checksum file (explicit opt-out) +gri --allow-missing-checksum install stackrox/kube-linter + # preview before installing gri --dry-run install junegunn/fzf gri --user --dry-run install gruntwork-io/terragrunt diff --git a/gri b/gri index cfec504..ef3ace9 100755 --- a/gri +++ b/gri @@ -6,6 +6,7 @@ BIN_DIR="${GRI_BIN_DIR:-/usr/local/bin}" GITHUB_API="https://api.github.com" DRY_RUN=0 USER_MODE=0 +ALLOW_MISSING_CHECKSUM=0 tmp_dir="" # build curl auth header from GITHUB_TOKEN if set @@ -417,7 +418,11 @@ cmd_install() { curl -sfL -o "${tmp_dir}/checksums" "$ck_url" verify_checksum "${tmp_dir}/${asset_name}" "$ck_algo" "${tmp_dir}/checksums" "$asset_name" else - echo "warning: no checksum file found in release assets, skipping verification" + if (( ALLOW_MISSING_CHECKSUM )); then + echo "warning: --allow-missing-checksum set, proceeding without verification" >&2 + else + die "no checksum file found in release assets\n → use --allow-missing-checksum to install without verification" + fi fi case "${asset_name,,}" in @@ -534,8 +539,9 @@ usage: gri [flags] remove remove an installed version flags (combinable, any position): - --user / -u install in ~/.local/opt and ~/.local/bin (no sudo required) - --dry-run / -n print what would happen without doing it + --user / -u install in ~/.local/opt and ~/.local/bin (no sudo required) + --dry-run / -n print what would happen without doing it + --allow-missing-checksum / -k proceed even if the release provides no checksum file environment: GRI_OPT_DIR override install base (/opt with default, ~/.local/opt with --user) @@ -560,8 +566,9 @@ EOF args=() for arg in "$@"; do case "$arg" in - --dry-run|-n) DRY_RUN=1 ;; - --user|-u) USER_MODE=1 ;; + --dry-run|-n) DRY_RUN=1 ;; + --user|-u) USER_MODE=1 ;; + --allow-missing-checksum|-k) ALLOW_MISSING_CHECKSUM=1 ;; *) args+=("$arg") ;; esac done From 54dd661661c96fd3a71968449f2ac9f09bba6fdd Mon Sep 17 00:00:00 2001 From: Giacomo Gorgellino Date: Tue, 16 Jun 2026 17:30:11 +0200 Subject: [PATCH 2/2] test: add tests for --allow-missing-checksum flag Co-Authored-By: Claude Sonnet 4.6 (1M context) --- test.sh | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/test.sh b/test.sh index e0d746a..1129d45 100755 --- a/test.sh +++ b/test.sh @@ -85,7 +85,40 @@ check_output "-n is alias for --dry-run" "\[dry-run\]" \ check_output "--dry-run flag accepted anywhere" "\[dry-run\]" \ "$GRI" install --dry-run junegunn/fzf -# ── 5. prefix comparison — staging-evil attack ──────────────────────────────── +# ── 5. allow-missing-checksum ──────────────────────────────────────────────── + +section "allow-missing-checksum" + +_ck_assets_none='[{"name":"tool-linux-amd64.tar.gz","browser_download_url":"http://x/tool.tar.gz"}]' +_ck_assets_present='[{"name":"tool-linux-amd64.tar.gz","browser_download_url":"http://x/tool.tar.gz"},{"name":"checksums.txt","browser_download_url":"http://x/checksums.txt"}]' + +check_fails "find_checksum_asset: no checksum asset returns 1" \ + find_checksum_asset "$_ck_assets_none" "tool-linux-amd64.tar.gz" + +check "find_checksum_asset: checksums.txt present returns 0" \ + find_checksum_asset "$_ck_assets_present" "tool-linux-amd64.tar.gz" + +check_output "missing checksum without flag: error mentions --allow-missing-checksum" \ + "allow-missing-checksum" \ + bash -c "source '$GRI' + assets=\$'[{\"name\":\"t.tar.gz\",\"browser_download_url\":\"http://x\"}]' + if ! find_checksum_asset \"\$assets\" 't.tar.gz'; then + (( ALLOW_MISSING_CHECKSUM )) \ + && echo 'warning: --allow-missing-checksum set, proceeding without verification' >&2 \ + || die 'no checksum file found in release assets\n → use --allow-missing-checksum to install without verification' + fi" + +check_output "missing checksum with --allow-missing-checksum: warning printed" \ + "proceeding without verification" \ + bash -c "source '$GRI'; ALLOW_MISSING_CHECKSUM=1 + assets=\$'[{\"name\":\"t.tar.gz\",\"browser_download_url\":\"http://x\"}]' + if ! find_checksum_asset \"\$assets\" 't.tar.gz'; then + (( ALLOW_MISSING_CHECKSUM )) \ + && echo 'warning: --allow-missing-checksum set, proceeding without verification' >&2 \ + || die 'no checksum file found' + fi" + +# ── 6. prefix comparison — staging-evil attack ─────────────────────────────── section "prefix comparison" @@ -105,7 +138,7 @@ check_fails "/stagingX is rejected" _prefix_check "/staging" "/stag check_fails "absolute escape is rejected" _prefix_check "/staging" "/etc/passwd" check_fails "sibling dir is rejected" _prefix_check "/staging" "/tmp/other" -# ── 6. archive security ─────────────────────────────────────────────────────── +# ── 7. archive security ─────────────────────────────────────────────────────── section "archive security" @@ -200,7 +233,7 @@ tar -czf "$TMPDIR_SEC/clean.tar.gz" -C "$TMPDIR_SEC/clean-src" mytool _expect_allow "tar: clean archive is allowed" \ "$TMPDIR_SEC/clean.tar.gz" tgz -# ── 7. smoke install (real network) ────────────────────────────────────────── +# ── 8. smoke install (real network) ────────────────────────────────────────── section "smoke install (network)"