Harden download -> verify -> execute chain (v1.121.9)#77
Merged
Conversation
Fixes from an adversarial audit of the installer download/verify/execute path (FileServer, Agent Installer, ISO download, Utilities staging). 39-FileServer.ps1: - Enforce a caller/config-supplied ExpectedHash even when the file server publishes no .sha256 sidecar (previously the configured hash was skipped in exactly its documented RMM use case, dropping to a weaker size-only prompt). A mismatch now fails closed. - Stop resending the Cloudflare Access token on HTTP redirects: the resume, HEAD, and hash-sidecar requests set AllowAutoRedirect=false, and the main download now streams via HttpWebRequest (no WebClient) and treats a 3xx as a hard failure. Avoids leaking the service token to a redirect target on another host, and dodges the WebClient-subclass Add-Type that can't compile on both PS 5.1 and pwsh 7. 57-AgentInstaller.ps1: - HashManifest lookup uses .ContainsKey (hashtable idiom) so ExpectedHash actually loads (the PSObject idiom returned .NET members, never the keys -> dead gate). - Reinstall/upgrade no longer reports SUCCESS from the pre-existing service on a timeout or Escape-skip; a skipped-but-running installer is left to finish. - Move the verified installer into an Administrators/SYSTEM-only stage before running it as SYSTEM (TOCTOU between verify and execute). - Quote space-bearing InstallArgs tokens so Start-Process doesn't re-split them. 35-Utilities.ps1: add Move-ToProtectedStaging helper (re-asserts an Admin+SYSTEM DACL each call, closing a pre-created-weak-dir gap the inline self-update copy has). 42-ISODownload.ps1: the low-space re-download bail restores the .old fallback and clears the script-scope rollback pointer instead of stranding it and mis-acting on a later download for a different version. Tests: Section 196 (17 asserts) + 3 stale tests updated to the new behavior; 5308/5308 passing. PSSA 0. Monolithic + version stamps -> 1.121.9.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes from an adversarial audit of the installer download → verify → execute chain (FileServer, Agent Installer, ISO download, Utilities staging). Verified findings only; each fix mirrors an existing in-repo hardening pattern.
FileServer (
39-FileServer.ps1)ExpectedHashwas skipped when the server published no.sha256sidecar — exactly its documented RMM use case — dropping to a weaker size-only prompt. It's now enforced inside the NoSidecar branch; a mismatch fails closed, a match is full verification.AllowAutoRedirect=$false; the main download now streams viaHttpWebRequest(noWebClient) and treats a3xxas a hard failure. This keeps the service token from being sent to a redirect target on another host — and avoids aWebClientsubclass (Add-Type) that can't compile on both Windows PowerShell 5.1 and pwsh 7 (verified). Redirect-refusal was proven with a localHttpListenertest (200 streams, 302 refused).Agent Installer (
57-AgentInstaller.ps1).ContainsKey(MEDIUM).$script:AgentInstalleris a hashtable, so the old.PSObject.Properties.Name -contains 'HashManifest'was always false →ExpectedHashnever loaded (the whole config-hash gate was dead). Now matches the correctRequireHashidiom.-not $preInstalledto claim success; a skipped-but-running installer is left to finish rather than killed.InstallArgstokens (/token "value with spaces") are quoted so PS 5.1'sStart-Processdoesn't re-split them.Utilities (
35-Utilities.ps1)Move-ToProtectedStaginghelper — re-asserts an Administrators+SYSTEM DACL on every call (closing a pre-created-weak-dir gap the inline self-update copy has).ISO download (
42-ISODownload.ps1).oldfallback and clears$script:_isoRollbackPath, instead of stranding the renamed ISO and mis-acting on a later download for a different version.Verification