Skip to content

security(dist): codesign-verify the fetched/remote cef_host (fail-closed, team-pinned)#17

Merged
wenkaifan0720 merged 1 commit into
mainfrom
fix/fetch-codesign-verify
Jul 3, 2026
Merged

security(dist): codesign-verify the fetched/remote cef_host (fail-closed, team-pinned)#17
wenkaifan0720 merged 1 commit into
mainfrom
fix/fetch-codesign-verify

Conversation

@wenkaifan0720

Copy link
Copy Markdown
Collaborator

Closes the top finding of the cef architecture audit: the auto-fetched cef_host executable was never authenticity-verified before use — the .sha256 sidecar lives in the same public bucket as the tarball, so it's transport integrity only.

Changes

  • fetch_cef_host.sh — staged extraction + fail-closed signature gate: codesign --verify --deep --strict with a designated requirement pinning the leaf cert to the publishing team (FLUTTER_CEF_TEAM_ID, default KLAJ5X6PJP). The app is only moved into native/cef_host/prebuilt/ after passing; a failure also drops the cached tarball. Offline-safe (no spctl).
  • publish-cef-host.sh — the "already exists → skip" idempotency now verifies the remote object's signature before trusting it (content-hash keys are computable from public sources, so a pre-planted object would otherwise permanently suppress the legitimate upload). Valid → no-op; invalid → hard error.

Validated (live)

  • Genuine GCS artifact: fetch verifies + installs ✅
  • Tampered binary with a matching attacker-controlled sha256 sidecar: REFUSED, nothing installed, cached tarball dropped ✅
  • Wrong team pin: refused ✅
  • Publish verify-remote against the genuine object: signature ok → no-op ✅

tool/ is outside the content hash — no artifact republish needed; consumers get the gate on their next pin bump.

🤖 Generated with Claude Code

…te cef_host (fail-closed)

The .sha256 sidecar lives in the same public GCS prefix as the tarball, so it is transport
integrity only — the actual root of trust is the Developer-ID signature sealed inside the app,
which nothing consulted before executing the fetched binary (posix_spawn bypasses Gatekeeper,
curl sets no quarantine).

- fetch_cef_host.sh: extract to a private staging dir, then REQUIRE `codesign --verify --deep
  --strict` with a designated requirement pinning the leaf cert to the publishing team
  (FLUTTER_CEF_TEAM_ID, default KLAJ5X6PJP) before moving the app into place. Fail-CLOSED on any
  mismatch (also drops the cached tarball). Offline-safe (no spctl/Gatekeeper round-trip).
- publish-cef-host.sh: the "already exists -> skip" idempotency no longer trusts a pre-existing
  remote object blindly (keys are content hashes of PUBLIC sources, so a bucket-writer could
  pre-plant an object for a future commit and permanently suppress the legitimate upload).
  It now downloads + signature-verifies the remote artifact: valid -> no-op as before; invalid ->
  hard error telling the operator to investigate/delete.

Validated live: genuine artifact fetch passes (team KLAJ5X6PJP); a tampered binary with a
matching (attacker-controlled) sha256 sidecar is REFUSED and nothing is installed; a wrong
FLUTTER_CEF_TEAM_ID is refused; publish verify-remote no-ops against the genuine GCS object.
tool/ is not part of the content hash, so no artifact republish is needed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@wenkaifan0720 wenkaifan0720 merged commit f4a43f0 into main Jul 3, 2026
1 check passed
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