Enforce SHA256 verification on every binary install path
Three gaps allowed an unverified binary to reach a trusted location: - The ffmpeg ZIP fallback logged a warning on checksum mismatch and installed anyway (the 7z path already aborted). Abort instead. - The yt-dlp auto-update path downloaded and renamed the binary over the verified one with no checksum at all. Verify against the official SHA2-256SUMS like the first-install path, and use atomic os.replace. - The yt-dlp first install streamed the download directly to the trusted path and only verified afterwards; a crash in between left an unverified executable to be run on next launch. Download to .part and os.replace only after verification. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -463,7 +463,7 @@ def update_yt_dlp() -> bool:
|
||||
|
||||
# Download the latest version
|
||||
try:
|
||||
response = requests.get(YTDLP_DOWNLOAD_URL, stream=True)
|
||||
response = requests.get(YTDLP_DOWNLOAD_URL, stream=True, timeout=60)
|
||||
if response.status_code == 200:
|
||||
# Create a temporary file
|
||||
temp_file = f"{yt_dlp_path}.new"
|
||||
@@ -472,21 +472,28 @@ def update_yt_dlp() -> bool:
|
||||
for chunk in response.iter_content(chunk_size=8192):
|
||||
f.write(chunk)
|
||||
|
||||
# Verify against the official checksums before touching the
|
||||
# trusted binary (same check as the first-install path)
|
||||
from ytsage.core.ytsage_yt_dlp import verify_ytdlp_sha256
|
||||
|
||||
if not verify_ytdlp_sha256(Path(temp_file), YTDLP_DOWNLOAD_URL):
|
||||
logger.error("SHA256 verification failed for yt-dlp update, keeping current binary")
|
||||
Path(temp_file).unlink(missing_ok=True)
|
||||
return False
|
||||
|
||||
# Make executable on Unix systems
|
||||
if OS_NAME != "Windows":
|
||||
os.chmod(temp_file, 0o755)
|
||||
|
||||
# Replace the old file with the new one
|
||||
# Replace the old file with the new one (os.replace is atomic
|
||||
# and overwrites on Windows too)
|
||||
try:
|
||||
# On Windows, we need to remove the old file first
|
||||
if OS_NAME == "Windows" and yt_dlp_path.exists():
|
||||
yt_dlp_path.unlink(missing_ok=True)
|
||||
|
||||
Path(temp_file).rename(yt_dlp_path)
|
||||
os.replace(temp_file, yt_dlp_path)
|
||||
logger.info("yt-dlp binary successfully updated")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.exception(f"Error replacing yt-dlp binary: {e}")
|
||||
Path(temp_file).unlink(missing_ok=True)
|
||||
return False
|
||||
else:
|
||||
logger.info(f"Failed to download latest yt-dlp: HTTP {response.status_code}")
|
||||
|
||||
Reference in New Issue
Block a user