Summary
Vendored dependencies (Git for Windows, Clink, ConEmu, Windows Terminal, clink-completions) are downloaded during the build without any integrity check. vendor/sources.json stores only name, version and url, so whatever file the URL returns is extracted and packaged into the Cmder release.
Where
scripts/build.ps1 downloads each source with Download-File and extracts it with no hash comparison.
scripts/update.ps1 selects the new URL by matching the newest GitHub release asset's filename to the old one. It doesn't record or check a hash.
.github/workflows/vendor.yml can push the updated sources.json directly to master when AUTO_MERGE_MINOR_VENDOR_UPDATES is enabled (opt-in, off by default).
Why it matters
If an upstream release is compromised, or an asset is replaced after publication, the change flows into Cmder's release packages. With auto-merge enabled, no human reviews it first. Pinning a hash turns a silent swap into a failed build.
Proposed fix
- Add a
sha256 field to each entry in vendor/sources.json.
- In
build.ps1, compute Get-FileHash -Algorithm SHA256 after each download and stop the build on a mismatch.
- In
update.ps1, fill in the new hash from the release asset's digest field in the GitHub API, which GitHub now provides for release assets. For archive/*.zip sources, which have no digest, compute the hash at update time.
- Require human review for any hash change, even when auto-merge is on. For example, keep auto-merge only when the diff is limited to
version/url/sha256 and upstream supplied the digest.
Related hardening (optional, same area)
update.ps1 accepts any host matching *github.com and allows http. Restrict it to https and exactly github.com.
Summary
Vendored dependencies (Git for Windows, Clink, ConEmu, Windows Terminal, clink-completions) are downloaded during the build without any integrity check.
vendor/sources.jsonstores onlyname,versionandurl, so whatever file the URL returns is extracted and packaged into the Cmder release.Where
scripts/build.ps1downloads each source withDownload-Fileand extracts it with no hash comparison.scripts/update.ps1selects the new URL by matching the newest GitHub release asset's filename to the old one. It doesn't record or check a hash..github/workflows/vendor.ymlcan push the updatedsources.jsondirectly tomasterwhenAUTO_MERGE_MINOR_VENDOR_UPDATESis enabled (opt-in, off by default).Why it matters
If an upstream release is compromised, or an asset is replaced after publication, the change flows into Cmder's release packages. With auto-merge enabled, no human reviews it first. Pinning a hash turns a silent swap into a failed build.
Proposed fix
sha256field to each entry invendor/sources.json.build.ps1, computeGet-FileHash -Algorithm SHA256after each download and stop the build on a mismatch.update.ps1, fill in the new hash from the release asset'sdigestfield in the GitHub API, which GitHub now provides for release assets. Forarchive/*.zipsources, which have nodigest, compute the hash at update time.version/url/sha256and upstream supplied thedigest.Related hardening (optional, same area)
update.ps1accepts any host matching*github.comand allowshttp. Restrict it tohttpsand exactlygithub.com.