Skip to content

fix: 14 security hardening fixes from deep audit#80

Merged
avrabe merged 3 commits intomainfrom
fix/security-hardening-round-1-2
Apr 14, 2026
Merged

fix: 14 security hardening fixes from deep audit#80
avrabe merged 3 commits intomainfrom
fix/security-hardening-round-1-2

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented Apr 14, 2026

Summary

Deep security audit (Mythos-style) of the entire codebase, identifying and fixing 14 vulnerabilities across crypto, verification, parsing, and attestation paths.

Critical (3)

  • SCT verification is a stubverify_sct() only checked signature length, not actual crypto. Marked as advisory-only with runtime warning until real ECDSA/Ed25519 verification is implemented
  • assert_eq! in production signing — crafted WASM with duplicate sig headers caused panic (DoS). Replaced with error return
  • Default CT log keys are placeholder — public keys ended in 0xdeadbeef. Added runtime warning

High (4)

  • Air-gapped verifier falls back to build timestampverify_signature() now fails closed when no time source configured
  • SecretKey implements Clone/Hash — removed dangerous derives, added Zeroizing wrappers for to_bytes()/to_pem()/to_der()
  • Negative integrated_time wraps to huge u64 — added sign check before cast in cert verification
  • Builder panics on missing fieldsTranscodingPredicateBuilder::build() now returns Result

Medium (7)

  • Silent certificate/signature drop in deserialization → fail on malformed
  • WASM section payload length unchecked → bounded to MAX_SLICE_LEN
  • Grace period has no maximum → capped at 365 days
  • Grace period arithmetic overflow → checked_add
  • Checkpoint size mismatch silently skips root hash check → log::warn
  • DSSE verify() accepts 1-of-N → security warning in docs

Test plan

  • cargo build — clean (5 kani warnings only)
  • cargo test — 766 passed, 0 failed, 3 ignored
  • All existing tests updated for new APIs (Result returns, with_keypair pattern)
  • CI pipeline (rust.yml, supply-chain.yml, wasm-signing.yml)

🤖 Generated with Claude Code

avrabe and others added 3 commits April 13, 2026 19:21
Round 1 (7 fixes):
- Fail closed when no time source in air-gapped verification (verifier.rs)
- Remove Clone/Hash derives from SecretKey and KeyPair (keys.rs)
- Return Zeroizing<Vec<u8>> from key serialization methods (keys.rs)
- Fail on malformed certificates/signatures instead of silent skip (sig_sections.rs)
- Add MAX_SLICE_LEN bounds to WASM section payload parsing (mod.rs)
- Cap grace period at 365 days with MAX_GRACE_PERIOD_SECONDS (bundle.rs)
- Use checked_add for grace period arithmetic to prevent overflow (bundle.rs)

Round 2 (7 fixes):
- Mark SCT verification as structural-only with runtime warning (sct.rs)
- Replace assert_eq! with error return in production signing path (multi.rs)
- Mark default CT log keys as placeholder with runtime warning (sct.rs)
- Reject negative integrated_time before i64→u64 cast (cert_verifier.rs)
- Convert TranscodingPredicateBuilder::build() to return Result (transcoding.rs)
- Document checkpoint consistency gap with log::warn (rekor_verifier.rs)
- Add security warning to DSSE verify() 1-of-N behavior (dsse.rs)

Supporting changes:
- Add SoftwareProvider::with_keypair() for borrowing without Clone
- Update tests and examples for new APIs

All 766 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The component crate calls SecretKey::to_bytes() and to_pem() which now
return Zeroizing wrappers. Convert back to plain types at the API
boundary since the WIT interface requires Vec<u8>/String.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Missed the keygen function which also returns SecretKey::to_bytes()
into a struct field expecting Vec<u8>.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@avrabe avrabe merged commit cddc81f into main Apr 14, 2026
14 of 21 checks passed
@avrabe avrabe deleted the fix/security-hardening-round-1-2 branch April 14, 2026 03:32
avrabe added a commit that referenced this pull request Apr 14, 2026
STPA artifact updates:
- Document R1+R2 fix status (14 fixes from PR #80)
- Add 3 new hazards: H-36 (cache flooding), H-37 (PATH injection),
  H-38 (MCUboot partial-image)
- Add 3 new system constraints: SC-34 (cache bound), SC-35 (build env
  path logging), SC-36 (MCUboot size validation)
- Add 3 new attack scenarios: AS-34, AS-35, AS-36

Code fixes:
- SC-34: MemoryProofCache now enforces max_entries (default 10,000)
  with oldest-entry eviction when at capacity
- SC-35: BuildEnvironment::capture() resolves and logs absolute paths
  of tool binaries, supports WSC_<TOOL>_PATH override env vars
- SC-36: MCUboot parser rejects images where trailing content exceeds
  8KB (MAX_TLV_OVERHEAD), preventing partial-image signature attacks

All 766 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
avrabe added a commit that referenced this pull request Apr 14, 2026
STPA artifact updates:
- Document R1+R2 fix status (14 fixes from PR #80)
- Add 3 new hazards: H-36 (cache flooding), H-37 (PATH injection),
  H-38 (MCUboot partial-image)
- Add 3 new system constraints: SC-34 (cache bound), SC-35 (build env
  path logging), SC-36 (MCUboot size validation)
- Add 3 new attack scenarios: AS-34, AS-35, AS-36

Code fixes:
- SC-34: MemoryProofCache now enforces max_entries (default 10,000)
  with oldest-entry eviction when at capacity
- SC-35: BuildEnvironment::capture() resolves and logs absolute paths
  of tool binaries, supports WSC_<TOOL>_PATH override env vars
- SC-36: MCUboot parser rejects images where trailing content exceeds
  8KB (MAX_TLV_OVERHEAD), preventing partial-image signature attacks

All 766 tests passing.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@avrabe avrabe mentioned this pull request Apr 14, 2026
2 tasks
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