Skip to content

install.sh: the sha256 and cosign fail-closed paths have no test #868

Description

@VijitSingh97

What

install.sh is the public curl-installer entry point (curl … | bash). It carries two security-critical fail-closed branches:

  • install.sh:60-63 — bundle sha256 vs the release manifest; on mismatch it must fail and install nothing.
  • install.sh:74-79cosign verify-blob against the repo-pinned key; a present-but-bad signature is meant to be fatal, while an absent one degrades to a note.

Neither is tested. The only coverage is tests/stack/run.sh:3774-3784, which stubs uname and asserts the two host gates:

assert_contains "install.sh refuses non-amd64" "$out" "x86_64-only"
assert_contains "install.sh refuses non-Linux" "$out" "runs on Linux"

Everything after the host gate — tag resolution, download, checksum verify, signature verify, the $DIR already-exists guard — is unexercised. Deleting the [ "$GOT" = "$WANT" ] comparison, or flipping the cosign check to non-fatal, keeps the suite green.

Why it matters

This is the path a new operator runs before they have any of the repo's other defenses. The in-bundle protections (verify_release_images, pinned digests) only start applying after a tampered bundle has already been extracted and executed.

Note the asymmetry these tests would pin down: a missing signature is a note, a bad one is fatal. That distinction is the whole security property and nothing currently holds it in place.

Tier

Tier 1, in tests/stack/run.sh, using the PATH-stub pattern the file already uses for uname. Stub curl to serve a fixture bundle + manifest, sha256sum, and cosign, then assert:

  • manifest sha256 mismatch → non-zero, nothing extracted, message names the refusal
  • manifest sha256 match → proceeds
  • manifest with no sha256 line → proceeds with the pre-v1.15 note (not a silent pass)
  • cosign present + signature present + verify fails → non-zero, nothing extracted
  • cosign present + no signature published → proceeds with the note
  • cosign absent → proceeds with the note
  • PITHEAD_DIR already exists → refuses before any download

install.sh execs ./pithead setup at the end, so the stub set needs a pithead that exits 0 for the positive cases.

Found during the develop-v2 quality pass (PR #867).

Metadata

Metadata

Assignees

No one assigned

    Labels

    appliancePithead OS appliance work — lands on feat/phase2-bakery-imagesecuritySecurity-sensitive issue or hardeningtestingTests, CI, and test infrastructure

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions