Skip to content

security(upgrade): harden self-update and installer verification - #572

Merged
ajianaz merged 1 commit into
developfrom
security/upgrade-hardening
Oct 7, 2026
Merged

ajianaz merged 1 commit into
developfrom
security/upgrade-hardening

Conversation

@ajianaz

@ajianaz ajianaz commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator

What

Hardens cora upgrade and install.sh: exact checksum matching, safe temp dir and extraction, bounded/time-limited downloads, and no silent checksum skip.

Why

Security review found several weak spots in the update path: substring checksum matching, a predictable /tmp/cora-update-{version} dir, full-archive unpack (symlink/hardlink entries), no timeouts or size caps, a single env var that silently disabled verification, and an installer that failed open when checksums were missing.

How

  • parse_checksum: exact filename equality after trimming a leading * or ./ (no more contains).
  • Temp dir via tempfile::tempdir() (random, 0700, cleaned on drop). tempfile moved from dev-dependencies to dependencies.
  • New extract_binary: rejects any symlink/hardlink or unsafe-path entry, extracts only the single regular-file cora entry (size capped).
  • HTTP clients: connect_timeout + timeout, streamed body with a hard size cap (256 MiB archive, 1 MiB checksums/API JSON), redirect(Policy::none()) for the /releases/latest Location probe, and release tags validated (vX.Y.Z..., safe chars) before being used in URLs.
  • CORA_UPGRADE_SKIP_CHECKSUM now errors unless CORA_UPGRADE_I_UNDERSTAND=1 is also set; when both are set a loud warning is printed. Not removed.
  • install.sh: verification is mandatory (missing checksums file or entry is fatal) unless CORA_SKIP_CHECKSUM=1; exact filename match; shasum -a 256 fallback; rejects symlink/hardlink entries; extracts only the binary entry.

Follow-up (not in this PR): signature verification (cosign/minisign) once there is key infrastructure.

Testing

  • cargo test --features tree-sitter passes
  • cargo fmt --all -- --check passes
  • cargo clippy --all-targets --features tree-sitter -- -D warnings passes
  • cargo build --release --features tree-sitter passes (not run; local disk was full)
  • Manual smoke-test: sh -n install.sh, awk checksum extraction checked against *name and .sig lines

New unit tests: exact checksum matching, skip-checksum gating, tag validation, tar extraction (regular file only, symlink/hardlink rejection, symlink named cora, missing binary). Network paths are not unit tested.

Related Issues

None.

Checklist

  • Branch name follows convention (security/)
  • Branch is from develop
  • Commit messages follow Conventional Commits
  • No secrets or credentials committed
  • One logical change per PR (no mixed concerns)

🤖 Generated with Claude Code

Exact-match checksum lookup, random 0700 temp dir, extract only the
regular-file binary entry (reject symlink/hardlink), request timeouts and
size caps, no-redirect version probe with tag validation, and require an
explicit ack to skip checksums. install.sh now fails closed on missing
checksums, falls back to shasum, and rejects link entries.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: ajianaz <ajianaz@users.noreply.github.com>
@ajianaz
ajianaz merged commit 9e8afeb into develop Oct 7, 2026
14 checks passed
ajianaz added a commit that referenced this pull request Oct 8, 2026
)

Covers security hardening (#563, #572, #573), fixes (#553, #561, #562,
#564, #565, #574-#576), and the ignore-pattern semantic changes from
#577 that can alter which files existing configs exclude.

Signed-off-by: ajianaz <ajianaz@users.noreply.github.com>
Co-authored-by: ajianaz <ajianaz@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5.5 <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.

1 participant