Repository navigation
fix: Verify installer script checksums before Unity Editor installs it - #1668
Conversation
The Unity Editor's remote install path used to fetch `install.sh` / `install.ps1` from `raw.githubusercontent.com` via a git tag and execute them without verification. Git tags can be moved after they are published, and `irm | iex` on Windows executes the fetched script straight from memory, so a compromised release could ship an unverified installer to any editor that runs the remote install command. Switch both platforms to the same flow that `uloop update` already uses: - Fetch the installer script and its `.sha256` sidecar from the dispatcher release assets (same generation as `uloop update`). - Verify SHA-256 with `sha256sum`/`shasum` on POSIX and `Get-FileHash` on Windows, comparing case-insensitively against the first token of the `.sha256` file (which contains `<hash> <filename>`). - On Windows, replace `irm | iex` with a temp-file download followed by `powershell -NoProfile -ExecutionPolicy Bypass -File $script`, wrapped in `try` / `finally` so the temp dir is removed on failure and `$LASTEXITCODE != 0` re-throws. - Chain the POSIX steps with `&&` (the whole command runs under a single `/bin/sh -c` where `set -e` is not applied for us) so a curl or checksum failure aborts before the script runs. The local script path used during package development is unchanged because it never fetches over the network, and `RAW_CONTENT_BASE_URL` in `CliConstants` is removed since it is no longer referenced from C#.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughNative CLI installer commands now use GitHub release assets for POSIX and Windows scripts, download matching ChangesNative CLI installer verification
Estimated code review effort: 4 (Complex) | ~40 minutes Sequence Diagram(s)sequenceDiagram
participant NativeCliCommandBuilder
participant GitHubReleaseAssets
participant TemporaryFiles
participant Installer
NativeCliCommandBuilder->>GitHubReleaseAssets: Download install script and .sha256 sidecar
GitHubReleaseAssets-->>TemporaryFiles: Store installer files
NativeCliCommandBuilder->>TemporaryFiles: Verify SHA256 checksum
NativeCliCommandBuilder->>Installer: Execute verified local script
Installer-->>NativeCliCommandBuilder: Return exit status
NativeCliCommandBuilder->>TemporaryFiles: Remove temporary files
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Set `$ErrorActionPreference = 'Stop'` inside the try block so that any non-terminating cmdlet error (missing checksum file, unexpected Get-FileHash result, etc.) throws immediately, instead of relying on a downstream null dereference to eventually raise an exception. The existing fail-close paths still work as before, but the intent is now explicit and no longer coupled to incidental error semantics.
Summary
install.sh/install.ps1from the same dispatcher release the CLI is being installed from, verify the shipped SHA-256, and only then run the script.User Impact
raw.githubusercontent.com/<repo>/dispatcher-vX.Y.Z/scripts/install.{sh,ps1}(a git tag ref) and executed it with no checksum. Windows piped the fetched script straight intoiex, so a tampered release could have run arbitrary code on the developer machine.uloop updatealready did — it downloads the release-asset installer plus its.sha256, verifies the hash, and executes the on-disk script. On Windows,irm | iexis gone; the script is saved to a temp file, verified, and re-launched viapowershell -NoProfile -ExecutionPolicy Bypass -File, withtry/finallycleaning up the temp directory even when verification or execution fails.Changes
https://github.com/hatayama/unity-cli-loop/releases/download/<dispatcher-tag>/install.{sh,ps1}) and add a matching.sha256sidecar URL. Both files are already produced byscripts/package-dispatcher.shand uploaded bydispatcher-publish.yml.mktemp -d+curl -fsSLfor the script and its.sha256,sha256sum -c(withshasum -a 256 -cfallback) run inside the temp dir so the checksum file name matches, thenULOOP_VERSION=<tag> sh $tmp/install.sh. Every step is&&-chained because the command runs under a single/bin/sh -cand cannot rely onset -e.Invoke-WebRequest -OutFileinto a per-run temp dir, compareGet-FileHash SHA256case-insensitively against the leading whitespace-delimited token of the.sha256(which contains<hash> <filename>), then& powershell -NoProfile -ExecutionPolicy Bypass -File $script_path.try/finallypropagates$LASTEXITCODEand removes the temp dir on failure.BuildPosixLocalInstallScriptCommand/BuildWindowsLocalInstallScriptCommand) is untouched because it never fetches over the network.CliConstants.RAW_CONTENT_BASE_URLis removed because no C# call site remains. README bootstrap URLs still point at raw content frommainand are unrelated.installer.go'sScriptURL(raw ref) is now referenced only by its own tests and is intentionally left alone per TODO 1 scope.Verification
dist/darwin-arm64/uloop compile --project-path <repo>→ 0 errors, 0 warnings.dist/darwin-arm64/uloop run-tests --project-path <repo> --filter-type regex --filter-value io\.github\.hatayama\.UnityCliLoop\.Tests\.Editor\.NativeCliInstallerTests --test-mode EditMode→ 30 passed, 0 failed.Refs: Obsidian TODO 1 — Unity Editor 側インストール経路の検証強化.