mirror of
https://github.com/usestrix/strix.git
synced 2026-09-24 00:51:20 +00:00
fix(install): verify SHA256SUMS before extract
Fail closed when the published checksum is missing or does not match the downloaded archive (#1267).
This commit is contained in:
parent
d61e0a2a63
commit
14b0aee28b
2 changed files with 84 additions and 7 deletions
|
|
@ -85,6 +85,8 @@ fi
|
|||
|
||||
filename="$APP-${specific_version}-${target}${archive_ext}"
|
||||
url="https://github.com/$REPO/releases/download/v${specific_version}/$filename"
|
||||
sums_name="SHA256SUMS"
|
||||
sums_url="https://github.com/$REPO/releases/download/v${specific_version}/$sums_name"
|
||||
bundle_name="strix-${target}.intoto.jsonl"
|
||||
bundle_url="https://github.com/$REPO/releases/download/v${specific_version}/$bundle_name"
|
||||
SIGNER_WORKFLOW="$REPO/.github/workflows/build-release.yml"
|
||||
|
|
@ -139,6 +141,55 @@ abort_unverified() {
|
|||
exit 1
|
||||
}
|
||||
|
||||
# Fail-closed checksum check against the published SHA256SUMS manifest.
|
||||
# Same-origin only (detects corruption / single-asset swap). Exact field
|
||||
# match — do not grep the filename as a regex ('.' would be wild).
|
||||
verify_checksum() {
|
||||
local file=$1
|
||||
|
||||
if [ -n "${STRIX_INSTALL_SKIP_VERIFY:-}" ]; then
|
||||
echo -e "${YELLOW}⚠ STRIX_INSTALL_SKIP_VERIFY set — skipping checksum verification (at your own risk).${NC}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local sha_cmd=""
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
sha_cmd="sha256sum"
|
||||
elif command -v shasum >/dev/null 2>&1; then
|
||||
sha_cmd="shasum -a 256"
|
||||
else
|
||||
echo -e "${RED}✗ Neither 'sha256sum' nor 'shasum' is available; cannot verify integrity.${NC}"
|
||||
abort_unverified
|
||||
fi
|
||||
|
||||
if [ ! -s "$sums_name" ]; then
|
||||
echo -e "${RED}✗ Missing checksum manifest ${sums_name}.${NC}"
|
||||
abort_unverified
|
||||
fi
|
||||
|
||||
echo -e "${MUTED}Verifying checksum...${NC}"
|
||||
|
||||
local expected
|
||||
expected=$(awk -v file="$file" '
|
||||
$2 == file || $2 == ("*" file) { print $1; exit }
|
||||
' "$sums_name")
|
||||
if [ -z "$expected" ]; then
|
||||
echo -e "${RED}✗ No SHA256SUMS entry for ${file}.${NC}"
|
||||
abort_unverified
|
||||
fi
|
||||
|
||||
local actual
|
||||
actual=$($sha_cmd "$file" | awk '{print $1}')
|
||||
if [ "$actual" != "$expected" ]; then
|
||||
echo -e "${RED}✗ Checksum mismatch for ${file}.${NC}"
|
||||
echo -e "${MUTED}Expected: ${NC}$expected"
|
||||
echo -e "${MUTED}Actual: ${NC}$actual"
|
||||
abort_unverified
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}✓ Checksum verified${NC}"
|
||||
}
|
||||
|
||||
gh_can_verify_attestation() {
|
||||
command -v gh >/dev/null 2>&1 && gh attestation verify --help >/dev/null 2>&1
|
||||
}
|
||||
|
|
@ -231,13 +282,23 @@ download_and_install() {
|
|||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${MUTED}Downloading provenance...${NC}"
|
||||
if ! curl -sfL -o "$bundle_name" "$bundle_url" || [ ! -s "$bundle_name" ]; then
|
||||
echo -e "${RED}✗ Failed to download provenance bundle.${NC}"
|
||||
abort_unverified
|
||||
fi
|
||||
if [ -n "${STRIX_INSTALL_SKIP_VERIFY:-}" ]; then
|
||||
echo -e "${YELLOW}⚠ STRIX_INSTALL_SKIP_VERIFY set — skipping checksum and provenance checks.${NC}"
|
||||
else
|
||||
echo -e "${MUTED}Downloading checksums...${NC}"
|
||||
if ! curl -sfL -o "$sums_name" "$sums_url" || [ ! -s "$sums_name" ]; then
|
||||
echo -e "${RED}✗ Failed to download checksum manifest.${NC}"
|
||||
abort_unverified
|
||||
fi
|
||||
verify_checksum "$filename"
|
||||
|
||||
verify_provenance "$filename" "$bundle_name"
|
||||
echo -e "${MUTED}Downloading provenance...${NC}"
|
||||
if ! curl -sfL -o "$bundle_name" "$bundle_url" || [ ! -s "$bundle_name" ]; then
|
||||
echo -e "${RED}✗ Failed to download provenance bundle.${NC}"
|
||||
abort_unverified
|
||||
fi
|
||||
verify_provenance "$filename" "$bundle_name"
|
||||
fi
|
||||
|
||||
echo -e "${MUTED}Extracting...${NC}"
|
||||
if [ "$os" = "windows" ]; then
|
||||
|
|
|
|||
|
|
@ -62,16 +62,32 @@ exit 1
|
|||
mock_bin / "curl",
|
||||
"""#!/bin/sh
|
||||
output=""
|
||||
url=""
|
||||
while [ "$#" -gt 0 ]; do
|
||||
if [ "$1" = "-o" ]; then
|
||||
output="$2"
|
||||
shift 2
|
||||
continue
|
||||
fi
|
||||
case "$1" in
|
||||
http://*|https://*) url="$1" ;;
|
||||
esac
|
||||
printf '%s\\n' "$1" >> "$STRIX_TEST_CURL_LOG"
|
||||
shift
|
||||
done
|
||||
cp "$STRIX_TEST_ARCHIVE" "$output"
|
||||
case "$url" in
|
||||
*/SHA256SUMS)
|
||||
hash=$(sha256sum "$STRIX_TEST_ARCHIVE" | awk '{print $1}')
|
||||
name=$(basename "$STRIX_TEST_ARCHIVE")
|
||||
printf '%s %s\\n' "$hash" "$name" > "$output"
|
||||
;;
|
||||
*.intoto.jsonl)
|
||||
printf '{"test":true}\\n' > "$output"
|
||||
;;
|
||||
*)
|
||||
cp "$STRIX_TEST_ARCHIVE" "$output"
|
||||
;;
|
||||
esac
|
||||
""",
|
||||
)
|
||||
return mock_bin
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue