Skip to content

security: verify integrity of downloaded scripts before execution#106

Merged
jacobtomlinson merged 1 commit intomainfrom
fix/install-checksum-verification
Mar 17, 2026
Merged

security: verify integrity of downloaded scripts before execution#106
jacobtomlinson merged 1 commit intomainfrom
fix/install-checksum-verification

Conversation

@ericksoa
Copy link
Copy Markdown
Contributor

@ericksoa ericksoa commented Mar 17, 2026

Summary

Fixes #57install.sh piped the nvm installer directly through curl | bash with no integrity check.

Fix: Downloads to a temp file, checks SHA-256 against a pinned digest, only executes on match. No new abstractions — the check is inlined at the one call site that needs it.

# Before
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash

# After
curl -fsSL "...nvm/v0.40.4/install.sh" -o "$nvm_tmp"
# SHA-256 check against pinned hash
bash "$nvm_tmp"
rm -f "$nvm_tmp"

Ollama stays as curl | sh — it's a rolling release URL that can't be pinned without breaking on every Ollama update, and the call is commented out in main() anyway.

Edge cases

Scenario Behavior
Hash matches Executes, prints "integrity verified"
Hash mismatch Deletes temp file, aborts with error showing both hashes
No sha256sum or shasum Warns, executes anyway (same posture as before)
Download fails Cleans up temp file, aborts

Test results

9 test cases, 25 assertions, all passing. Tests ran on macOS and in Docker (ubuntu:24.04).

# Scenario Assertions Result
1 Pinned hash matches real nvm v0.40.4 (independently downloaded and SHA-256 verified) 1 PASS
2 Happy path — correct hash verifies and executes 3 PASS
3 Tampered file — hash mismatch aborts, shows expected vs actual hashes 5 PASS
4 Empty hash (Ollama path) — skips verification, still executes 3 PASS
5 No hash tools available — warns and executes (same security posture as before) 3 PASS
6 Temp file cleanup after both success and failure 2 PASS
7 Bad URL — errors cleanly with "Failed to download" 2 PASS
8 shasum fallback works when sha256sum unavailable (macOS compat) 2 PASS
9 Static analysis — zero curl | bash pipes remain in nvm install path 4 PASS

Total: 25 assertions, 0 failures

Test plan for CI pipeline

These test cases should be automated when the build pipeline is set up:

TC1 — Hash correctness: Download nvm installer independently, compute SHA-256, assert it matches the pinned NVM_SHA256 value in install.sh. This catches stale hashes after version bumps.

TC2 — Verification pass: Serve a known file via python3 -m http.server, call the inline verification logic with the correct hash, assert exit 0 and "integrity verified" in output.

TC3 — Verification fail (tampered): Serve a file, call with a wrong hash, assert exit non-zero, output contains "integrity check failed" with both expected and actual hashes, and the file was not executed.

TC4 — Empty hash passthrough: Call with empty expected hash, assert file is still executed without verification errors.

TC5 — No hash tool fallback: Run in a container with sha256sum and shasum removed from PATH, assert warning "No SHA-256 tool found" is printed and the script still executes.

TC6 — Temp file cleanup: Assert no orphaned temp files exist after both successful and failed verification runs.

TC7 — Download failure: Call with a non-existent URL, assert exit non-zero and "Failed to download" in output.

TC8 — shasum fallback (macOS): Run in an environment with only shasum (no sha256sum), assert verification succeeds with the correct hash.

TC9 — No curl|bash pipes: grep -cE 'curl.*\|.*(bash|sh)' install.sh on the nvm install path returns 0. Ollama (commented out) is excluded from this check.

install.sh downloaded the nvm installer via curl | bash with no
integrity check. A MITM or CDN compromise could substitute a backdoored
script that runs with full host privileges before any sandbox is
established.

Now downloads to a temp file, checks SHA-256 against a pinned digest,
and only executes on match. Ollama installer is left as-is (rolling
release URL that can't be pinned, and the call is commented out).

Closes #57

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ericksoa ericksoa force-pushed the fix/install-checksum-verification branch from 87ef69e to 171222d Compare March 17, 2026 02:18
Copy link
Copy Markdown
Member

@jacobtomlinson jacobtomlinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested in a fresh ubuntu container

@jacobtomlinson jacobtomlinson merged commit 3baea92 into main Mar 17, 2026
jessesanford pushed a commit to jessesanford/NemoClaw that referenced this pull request Mar 24, 2026
…IDIA#106)

install.sh downloaded the nvm installer via curl | bash with no
integrity check. A MITM or CDN compromise could substitute a backdoored
script that runs with full host privileges before any sandbox is
established.

Now downloads to a temp file, checks SHA-256 against a pinned digest,
and only executes on match. Ollama installer is left as-is (rolling
release URL that can't be pinned, and the call is commented out).

Closes NVIDIA#57

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Security] install.sh fetches and executes remote assets without integrity verification

2 participants