fix(design): verify the whiteboard bundle against SHA256SUMS before unpacking - #204
Merged
Conversation
…npacking The whiteboard tarball was fetched from GitHub Releases and piped straight into tar: no digest check, no timeout, no abort signal, and a failing tar surfaced as a bare Error. The release build already publishes SHA256SUMS next to the tarball, so the loader now downloads that first, finds the line for redcode-whiteboard-<version>.tar.gz, hashes the archive with Bun.CryptoHasher, and refuses to unpack on a missing entry or a mismatch. Both downloads carry a 60 s AbortSignal.timeout, tar's exit code and stderr become a Design.Error, and an archive without whiteboard.js is rejected before the temp directory is renamed into place. Every failure keeps the existing `unavailable` semantics (409) and leaves the release directory absent so the next call retries. The release source (fetch, version, data dir, checkout dir, timeout) is a module-level Source with a configure() entry point, so the test suite serves a tarball and SHA256SUMS from memory and covers: a verified unpack that is then served from cache, a mismatched digest that caches nothing and retries, a tarball missing from SHA256SUMS, a 404 on SHA256SUMS, a network error and a timed-out download, and a listed archive that tar cannot unpack. Claude-Session: https://claude.ai/code/session_01KAcoL6wpgVEs2ebUrUGpHS
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.
Problem
packages/core/src/design/whiteboard.tsfetched the whiteboard release tarball from GitHub Releases and piped it straight intotar -xzf: no checksum verification, no fetch timeout or abort signal, and a non-zerotarexit surfaced as a bareError. The release build already generates and uploadsSHA256SUMSalongside the tarball (packages/redcode/script/build.ts), but the loader never read it.Fix
SHA256SUMSfrom the same release, find the<sha256> redcode-whiteboard-<version>.tar.gzline, hash the tarball withBun.CryptoHasher, and refuse to unpack on a missing entry or a mismatch.AbortSignal.timeout; HTTP errors, network errors and timeouts all becomeDesign.Errorunavailable(still 409) with a message naming the asset and the reason.tarexit code and stderr become aDesign.Error; an archive that unpacks withoutwhiteboard.jsis rejected too. Extraction still happens in a temp directory that is only renamed into place after every check, so a partial install is never seen as cached and the next call retries.fetch,version,data,checkout,timeout) is a module-levelSourcewith aconfigure()entry point so tests can serve a release from memory. Build script untouched.Test
packages/core/test/design-whiteboard.test.tsgains six tests that serve a local tarball +SHA256SUMSthrough the injectedfetch:unavailable, caches nothing, and the next call re-downloads and succeedsSHA256SUMSfails before the tarball is requestedSHA256SUMS404 fails withunavailableunavailabletarcannot unpack fails cleanly with the exit code, nothing cachedBefore the fix: 0 pass / 8 fail (the original loader has no injection point,
configureis not a function). After: 8 pass / 0 fail (PLAYWRIGHT_BROWSERS_PATH=~/.cache/ms-playwright mise x -- bun test --timeout 30000 test/design-whiteboard.test.ts).bun run typecheckclean inpackages/coreandpackages/redcode.https://claude.ai/code/session_01KAcoL6wpgVEs2ebUrUGpHS
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.