fix: check the uv installer against a pinned sha256 before running it

Both installers download the pinned uv installer to a file and run it only
when its sha256 matches the value pinned next to UV_VERSION; bumping the
version means bumping the hash. Astral publishes checksums for the uv
binaries but not for the installer scripts, so the hash is pinned here.

get.docker.com is still only downloaded in full before running: its content
changes over time and it publishes no checksum.
This commit is contained in:
Alex committed 2026-09-16 01:10:11 +01:00
1 parent 0e1963552c
commit 7e80f7a091
2 files changed
+46 -9

No files matched your search

+17 -3
View File
@@ -23,6 +23,9 @@ function Install-DocsGPT {
$ErrorActionPreference = 'Stop'
$UvVersion = '0.12.15'
$UvMinVersion = [version]'0.8.0'
# sha256 of https://astral.sh/uv/$UvVersion/install.ps1, checked before it runs. Bump it with
# $UvVersion: (Invoke-WebRequest "https://astral.sh/uv/<version>/install.ps1").Content | …
$UvInstallerSha256 = '63f2d7e2ccc347cc018127b22f56f569080e5730a390dcb702b654daf6822193'
function Say([string]$Message) { Write-Host "==> $Message" }
@@ -50,9 +53,20 @@ function Install-DocsGPT {
$env:UV_INSTALL_DIR = $uvDir
$env:UV_NO_MODIFY_PATH = '1'
$env:UV_PRINT_QUIET = '1'
# A child PowerShell, so nothing the uv installer does can end this session.
$shell = (Get-Process -Id $PID).Path
& $shell -NoProfile -ExecutionPolicy Bypass -Command "irm https://astral.sh/uv/$UvVersion/install.ps1 | iex"
# Downloaded and checked before it runs, and run in a child PowerShell so nothing the
# uv installer does can end this session.
$installer = Join-Path ([System.IO.Path]::GetTempPath()) "uv-installer-$UvVersion.ps1"
try {
Invoke-WebRequest -Uri "https://astral.sh/uv/$UvVersion/install.ps1" -OutFile $installer -UseBasicParsing
$actual = (Get-FileHash -Path $installer -Algorithm SHA256).Hash.ToLower()
if ($actual -ne $UvInstallerSha256) {
throw "The uv installer does not match its pinned sha256: got $actual, expected $UvInstallerSha256. Refusing to run it."
}
$shell = (Get-Process -Id $PID).Path
& $shell -NoProfile -ExecutionPolicy Bypass -File $installer
} finally {
Remove-Item $installer -Force -ErrorAction SilentlyContinue
}
$uv = Join-Path $uvDir 'uv.exe'
if (-not (Test-Path $uv)) { throw "uv did not install into $uvDir" }
}
+29 -6
View File
@@ -20,6 +20,9 @@
UV_VERSION="0.12.15"
UV_MIN_VERSION="0.8.0"
# sha256 of https://astral.sh/uv/$UV_VERSION/install.sh, checked before it runs. Bump it with
# UV_VERSION: curl -fsSL https://astral.sh/uv/<version>/install.sh | shasum -a 256
UV_INSTALLER_SHA256="716a1d6844740756c68770fcec2f79c2013fb9b03869a113f61e15f6f482a6a1"
main() {
set -euo pipefail
@@ -47,16 +50,33 @@ main() {
die "curl or wget is needed to download $1"
fi
}
# run_downloaded URL COMMAND...: save URL to a file, then run COMMAND with the file as its last
# argument. A transfer cut short fails before anything runs.
sha256_of() {
if has shasum; then
shasum -a 256 "$1" | awk '{print $1}'
elif has sha256sum; then
sha256sum "$1" | awk '{print $1}'
else
die "neither shasum nor sha256sum is available to check $1"
fi
}
# run_downloaded URL SHA256 COMMAND...: save URL to a file, check it against SHA256 ("-" to
# skip), then run COMMAND with the file as its last argument. A transfer cut short, or content
# that does not match, fails before anything runs.
run_downloaded() {
local url="$1" script status=0
shift
local url="$1" expected="$2" script status=0 actual
shift 2
script="$(mktemp)"
if ! download "$url" >"$script"; then
rm -f "$script"
die "could not download $url"
fi
if [ "$expected" != "-" ]; then
actual="$(sha256_of "$script")"
if [ "$actual" != "$expected" ]; then
rm -f "$script"
die "$url does not match its pinned sha256: got $actual, expected $expected. Refusing to run it."
fi
fi
"$@" "$script" || status=$?
rm -f "$script"
return "$status"
@@ -96,7 +116,9 @@ main() {
sudo="sudo"
fi
say "Installing Docker"
run_downloaded https://get.docker.com $sudo sh
# Docker's script changes over time and publishes no checksum, so it is only downloaded
# in full before it runs.
run_downloaded https://get.docker.com - $sudo sh
$sudo systemctl enable --now docker >/dev/null 2>&1 || true
if [ -n "$sudo" ]; then
$sudo usermod -aG docker "$(id -un)"
@@ -122,7 +144,8 @@ main() {
if [ -z "$uv" ]; then
local uv_dir="${XDG_BIN_HOME:-$HOME/.local/bin}"
say "Installing uv $UV_VERSION into $uv_dir"
run_downloaded "https://astral.sh/uv/$UV_VERSION/install.sh" env UV_INSTALL_DIR="$uv_dir" UV_NO_MODIFY_PATH=1 UV_PRINT_QUIET=1 sh
run_downloaded "https://astral.sh/uv/$UV_VERSION/install.sh" "$UV_INSTALLER_SHA256" \
env UV_INSTALL_DIR="$uv_dir" UV_NO_MODIFY_PATH=1 UV_PRINT_QUIET=1 sh
uv="$uv_dir/uv"
[ -x "$uv" ] || die "uv did not install into $uv_dir"
fi