mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
install.ps1: report checksum-verified layout mismatch separately from unsafe archive
Refs #1218 Signed-off-by: Mukkara Rithvik Reddy <rithvikreddymukkara@gmail.com>
This commit is contained in:
1 parent
10ab613de3
commit
2809f88d6e
2 files changed
+58
-3
No files matched your search
+32
-3
@@ -277,8 +277,20 @@ try {
|
||||
|
||||
# Validate the zip namespace before extraction. Windows paths are
|
||||
# case-insensitive, so two entries that differ only in case are ambiguous and
|
||||
# must never be allowed to overwrite each other. The official five entries are
|
||||
# must never be allowed to overwrite each other. The official four entries are
|
||||
# required at the archive root with their exact release names.
|
||||
#
|
||||
# Two failure classes are reported differently (both still exit 1; nothing is
|
||||
# relaxed). An unsafe entry path or a duplicate/case-conflicting entry is a
|
||||
# hostile archive shape. A well-formed archive whose root file SET differs from
|
||||
# $WindowsArchiveNames already passed checksum verification above, so it is
|
||||
# the published artifact for $BaseUrl -- the usual cause is this script being
|
||||
# newer or older than that release (e.g. install.ps1 run from main ahead of
|
||||
# the latest release, #1218). Calling that "unsafe" sends the user hunting for
|
||||
# tampering that is not there. Every entry is screened for the hostile class
|
||||
# BEFORE any layout verdict, so a bad path can never hide behind a layout
|
||||
# message just because an unexpected entry happened to come first.
|
||||
$LayoutMismatch = $false
|
||||
try {
|
||||
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
||||
$zip = [System.IO.Compression.ZipFile]::OpenRead("$TmpDir\$Archive")
|
||||
@@ -286,6 +298,7 @@ try {
|
||||
$seen = New-Object 'System.Collections.Generic.HashSet[string]' ([System.StringComparer]::OrdinalIgnoreCase)
|
||||
$archiveCounts = @{}
|
||||
foreach ($archiveName in $WindowsArchiveNames) { $archiveCounts[$archiveName] = 0 }
|
||||
$layoutProblem = $null
|
||||
foreach ($entry in $zip.Entries) {
|
||||
$entryName = $entry.FullName.Replace('\', '/')
|
||||
$isDirectory = $entryName.EndsWith('/')
|
||||
@@ -304,10 +317,16 @@ try {
|
||||
throw "duplicate or case-conflicting zip entry: $($entry.FullName)"
|
||||
}
|
||||
if (-not ($WindowsArchiveNames -ccontains $entryName) -or $isDirectory) {
|
||||
throw "archive contains an unexpected root entry: $($entry.FullName)"
|
||||
if ($null -eq $layoutProblem) {
|
||||
$layoutProblem = "archive contains an unexpected root entry: $($entry.FullName)"
|
||||
}
|
||||
continue
|
||||
}
|
||||
$archiveCounts[$entryName] = $archiveCounts[$entryName] + 1
|
||||
}
|
||||
# Every entry passed the hostile-shape checks; only now judge the layout.
|
||||
$LayoutMismatch = $true
|
||||
if ($null -ne $layoutProblem) { throw $layoutProblem }
|
||||
foreach ($archiveName in $WindowsArchiveNames) {
|
||||
if ($archiveCounts[$archiveName] -ne 1) {
|
||||
throw "archive must contain exactly one $archiveName"
|
||||
@@ -316,11 +335,21 @@ try {
|
||||
if ($seen.Count -ne $WindowsArchiveNames.Count) {
|
||||
throw "archive does not match the exact Windows release allowlist"
|
||||
}
|
||||
$LayoutMismatch = $false
|
||||
} finally {
|
||||
$zip.Dispose()
|
||||
}
|
||||
} catch {
|
||||
Write-Host "error: unsafe or incomplete release archive: $_" -ForegroundColor Red
|
||||
if ($LayoutMismatch) {
|
||||
Write-Host "error: release archive layout does not match this installer: $_" -ForegroundColor Red
|
||||
Write-Host " The archive matched the checksum published with it at $BaseUrl, so it is"
|
||||
Write-Host " the genuine release artifact, built for a different installer version."
|
||||
Write-Host " This installer expects: $($WindowsArchiveNames -join ', ')"
|
||||
Write-Host " Fix: run the install.ps1 shipped inside that same release archive, or"
|
||||
Write-Host " re-run this script after the next release is published."
|
||||
} else {
|
||||
Write-Host "error: unsafe release archive: $_" -ForegroundColor Red
|
||||
}
|
||||
Remove-Item -Recurse -Force $TmpDir -ErrorAction SilentlyContinue
|
||||
exit 1
|
||||
}
|
||||
|
||||
@@ -335,6 +335,32 @@ for relative, needles in exact_archive_guards.items():
|
||||
"allowlist",
|
||||
)
|
||||
|
||||
# install.ps1 reports two different archive failures differently (#1218). A
|
||||
# checksum-verified archive whose root file set differs from the allowlist is a
|
||||
# release/installer version skew, not tampering, and must say so; a hostile
|
||||
# entry (unsafe path, duplicate or case conflict) stays "unsafe". Both exit 1.
|
||||
# The layout verdict may only be reached after EVERY entry cleared the hostile
|
||||
# checks, or an unexpected entry listed first would mask a later "../" entry.
|
||||
installer_archive = read("install.ps1")
|
||||
require(
|
||||
"unsafe or incomplete release archive" not in installer_archive
|
||||
and "error: unsafe release archive: " in installer_archive
|
||||
and "error: release archive layout does not match this installer: " in installer_archive,
|
||||
"install.ps1 must report a checksum-verified layout mismatch separately from an unsafe "
|
||||
"archive (#1218)",
|
||||
)
|
||||
hostile_last = max(
|
||||
installer_archive.find('throw "unsafe zip entry path:'),
|
||||
installer_archive.find('throw "duplicate or case-conflicting zip entry:'),
|
||||
)
|
||||
layout_verdict = installer_archive.find("$LayoutMismatch = $true")
|
||||
require(
|
||||
hostile_last != -1 and layout_verdict > hostile_last
|
||||
and installer_archive.count("$LayoutMismatch = $true") == 1,
|
||||
"install.ps1 must screen every zip entry for unsafe paths and duplicates before it "
|
||||
"classifies an archive as a layout mismatch (#1218)",
|
||||
)
|
||||
|
||||
# A portable mutation refusal must point to the owning package manager.
|
||||
guidance_contracts = {
|
||||
"pkg/npm/bin.js": (
|
||||
|
||||
Reference in new issue
Block a user