mirror of
https://github.com/luxfi/mpc.git
synced 2026-09-24 00:26:24 +00:00
Red round 4 flagged (F4, MEDIUM-HIGH) that the previous LAX binding mode in VerifyLiveness permitted a cross-ceremony replay: an attacker who observed a fresh WebAuthn challenge could trick into signing a liveness envelope binding to the challenge alone (no credentialHash), then replay that envelope against any enrollment for the same userId that happened to reuse the challengeId-only expectation. Two LAX-only tightenings in pkg/webauthn/liveness.go (STRICT already enforced the missing-both rejection; this sharpens LAX): 1. credentialHash is a hard floor. If the server expects credentialHash and the envelope omits it, reject with "credentialHash required in LAX mode — envelope without credentialHash is replay-vulnerable". challengeId alone cannot satisfy the binding requirement in LAX — challengeId can be observed and replayed; credentialHash commits to the specific pubKey being enrolled. 2. When the envelope supplies BOTH credentialHash AND challengeId AND the server expects both, require BOTH to match. No more "either-or" loophole. The existing mismatch-rejects guards already caught individual mismatches; this closes the pathological both-supplied-one-blank-expected corner. handleBiometricEnroll always commits ExpectedCredentialHash (derived from the enrollment pubKey via sha256), so the LAX floor always engages in practice for WebAuthn enrollment — this hardens what is already the exercised path. Test coverage (pkg/webauthn/liveness_test.go): - TestLiveness_R38_LaxRejectsMissingCredentialHash — primary F4 gate: envelope with only challengeId, missing credentialHash → reject - TestLiveness_R38_LaxAcceptsBothMatch — happy path (extended envelope after rollout) - TestLiveness_R38_LaxRejectsMismatchedCredentialHashBothPresent - TestLiveness_R38_LaxRejectsMismatchedChallengeIDBothPresent - TestLiveness_R38_LaxAcceptsCredentialHashOnly — current envelope shape still accepted - TestLiveness_R38_LaxRejectsMissingBindingWhenCredentialHashExpected — replaces the old lax-warns-missing path - TestLiveness_R38_LaxWarnsOnMissing_ChallengeIDOnly — warn path still available when credentialHash is not expected Full pkg/webauthn suite green (18/18). pkg/api regression tests pass. pkg/custody pre-existing failures unrelated to this change (SQLite json_extract missing, blame predates F4). LLM.md entry R35 documents the full set. Cut v1.7.1 on merge.