Summary
build_collector_macos.sh (the local-dev build script) does not apply any download-integrity / race guard to the Linux.Triage.UAC.zip artifact, even though it guards the Windows.Triage.Targets.zip artifact in the same script, and build_collector.sh (the CI/release script) guards both.
Details
After PR #16, both artifact downloads in build_collector.sh call the shared verify_download_not_raced helper, and the Windows download in build_collector_macos.sh does too. But the Linux artifact block in build_collector_macos.sh just downloads and unzips with no guard:
# build_collector_macos.sh — Linux.Triage.UAC block (no guard)
download_with_retry "$LINUX_ARTIFACT_URL" "Linux.Triage.UAC.zip" || exit 1
LINUX_ARTIFACT_SHA256=$(shasum -a 256 Linux.Triage.UAC.zip | cut -d' ' -f1)
echo "Linux.Triage.UAC.zip SHA256: $LINUX_ARTIFACT_SHA256"
unzip -o Linux.Triage.UAC.zip -d ./datastore/artifact_definitions/Linux/Triage
rm Linux.Triage.UAC.zip
Two related asymmetries on this path:
- No race guard — unlike
build_collector.sh, there's no post-download verify_download_not_raced call for the Linux artifact.
- No ETag/SHA tamper handling —
build_collector_macos.sh computes the SHA256 but never persists ETags to metadata, so its Windows-side stored-hash tamper check can never fire either (it's gated on a matching stored ETag).
Impact
Low / local-only. build_collector_macos.sh is a developer convenience for building on a Mac; it is not invoked by CI (.github/workflows/ci.yml runs build_collector.sh), so the released collectors are unaffected. The gap only matters for someone building locally with this script, who would get no signal if Linux.Triage.UAC.zip were swapped mid-build.
Why filed separately
This is pre-existing (predates the macOS-collector and ETag-race work) and was explicitly kept out of scope of PR #14/#15/#16 to keep those changes focused.
Suggested fix
The shared helper now makes the race-guard half a near one-liner. Either:
- Fetch a
LINUX_TRIAGE_ETAG in build_collector_macos.sh and call verify_download_not_raced "$LINUX_ARTIFACT_URL" "Linux.Triage.UAC.zip" "$LINUX_TRIAGE_ETAG" "Linux.Triage.UAC" (matching build_collector.sh), or
- Consolidate
build_collector.sh and build_collector_macos.sh into one parameterized script so this kind of per-artifact / per-script drift can't recur (the two scripts already share ~70% of their logic via lib/collector_common.sh).
Summary
build_collector_macos.sh(the local-dev build script) does not apply any download-integrity / race guard to theLinux.Triage.UAC.zipartifact, even though it guards theWindows.Triage.Targets.zipartifact in the same script, andbuild_collector.sh(the CI/release script) guards both.Details
After PR #16, both artifact downloads in
build_collector.shcall the sharedverify_download_not_racedhelper, and the Windows download inbuild_collector_macos.shdoes too. But the Linux artifact block inbuild_collector_macos.shjust downloads and unzips with no guard:Two related asymmetries on this path:
build_collector.sh, there's no post-downloadverify_download_not_racedcall for the Linux artifact.build_collector_macos.shcomputes the SHA256 but never persists ETags to metadata, so its Windows-side stored-hash tamper check can never fire either (it's gated on a matching stored ETag).Impact
Low / local-only.
build_collector_macos.shis a developer convenience for building on a Mac; it is not invoked by CI (.github/workflows/ci.ymlrunsbuild_collector.sh), so the released collectors are unaffected. The gap only matters for someone building locally with this script, who would get no signal ifLinux.Triage.UAC.zipwere swapped mid-build.Why filed separately
This is pre-existing (predates the macOS-collector and ETag-race work) and was explicitly kept out of scope of PR #14/#15/#16 to keep those changes focused.
Suggested fix
The shared helper now makes the race-guard half a near one-liner. Either:
LINUX_TRIAGE_ETAGinbuild_collector_macos.shand callverify_download_not_raced "$LINUX_ARTIFACT_URL" "Linux.Triage.UAC.zip" "$LINUX_TRIAGE_ETAG" "Linux.Triage.UAC"(matchingbuild_collector.sh), orbuild_collector.shandbuild_collector_macos.shinto one parameterized script so this kind of per-artifact / per-script drift can't recur (the two scripts already share ~70% of their logic vialib/collector_common.sh).