From e9f05a6f7d334500839e2294dfa52b1f9650aaa7 Mon Sep 17 00:00:00 2001 From: NX1X Date: Sun, 6 Sep 2026 21:45:55 +0300 Subject: [PATCH] security: pin vendored library hashes in check-cdn-versions.sh The vendoring of pdf.js/SheetJS off cdnjs dropped SRI, and the version check that replaced it only verified the three files existed and were referenced by name - it never checked content. A tampered vendor file (bad merge, compromised local write, mismatched copy) passed CI green. Pin the current sha256 of each vendored file and verify it on every run; a mismatch now fails the check with the actual vs expected hash. --- scripts/check-cdn-versions.sh | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/scripts/check-cdn-versions.sh b/scripts/check-cdn-versions.sh index ef825c2..d0daa1e 100755 --- a/scripts/check-cdn-versions.sh +++ b/scripts/check-cdn-versions.sh @@ -12,13 +12,32 @@ cd "$(dirname "$0")/.." fail=0 +# Pin the exact bytes we vendored, not just their presence. Bump these +# together with the file, deliberately, when updating a library version. +declare -A EXPECTED_SHA256=( + ["public/vendor/pdf.min.js"]="5b5799e6f8c680663207ac5b42ee14eed2a406fa7af48f50c154f0c0b1566946" + ["public/vendor/pdf.worker.min.js"]="feabdf309770ed24bba31a5467836cdc8cf639c705af27d52b585b041bb8527b" + ["public/vendor/xlsx.full.min.js"]="c9506197caf809a075b6dee1da0d36fb19da7158ffe8a88e7b0c96c5d8623c99" +) + check_vendored_file() { local path="$1" if [ ! -f "$path" ]; then echo "MISSING: ${path} does not exist" fail=1 + return + fi + local expected="${EXPECTED_SHA256[$path]:-}" + local actual + actual="$(sha256sum "$path" | cut -d' ' -f1)" + if [ -z "$expected" ]; then + echo "OK: ${path} present (no pinned hash on record - add one)" + fail=1 + elif [ "$actual" != "$expected" ]; then + echo "TAMPERED OR STALE: ${path} sha256=${actual}, expected ${expected}" + fail=1 else - echo "OK: ${path} present" + echo "OK: ${path} present, sha256 matches" fi }