-- user_verified — a PIN/biometric (not mere presence) was performed at bind. With the
-- required-UV policy this is always true for new rows, but persisting
-- it survives a future policy that permits UV=preferred credentials.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
问题
webauthn_credentials上持久化了每个凭据的user_verified/backup_eligible/backup_state,但没有任何断言路径读它们。目前的保证来自全局策略 —— 注册和 discoverable login 都写死VerificationRequired—— 而不是来自这几列。现在这不构成漏洞:全局要求 UV,所以每一行的
user_verified都是 true。它在两种情况下变成问题:策略放宽到preferred,或者引入一条不走这两个入口的登录/提权路径。migration 0009 的注释本身就是这么写的。证据
Identified by Claude Opus 5 (claude-opus-5) while auditing the WebAuthn subsystem's persisted flags on 2026-07-28.
internal/store/migrations/0009_*.sql存了这三列,注释写明用意:消费侧目前只有全局策略两处,没有按凭据的判定:
internal/passkey/verifier.go:74—UserVerification: protocol.VerificationRequiredinternal/passkey/verifier.go:229—BeginDiscoverableLogin(webauthn.WithUserVerification(protocol.VerificationRequired))grep -rn "user_verified" --include=*.go internal/在断言路径上没有命中。验收
断言完成时按凭据校验 UV:一个
user_verified = false的凭据在需要 UV 的操作上被拒绝。备注
这条属于 task #40(passkey 登录/提权)的范围,在那条落地之前没有单独做的必要 —— 现在没有断言路径可以挂。开这条是为了别在建 #40 的时候把这个已经存好的信息忘掉,重新去做一个全局开关。
9ab7b27落地:applyAssertion 是三个断言入口(用户名登录、无用户名登录、提权/迁移确认)共用的唯一判定点,要求凭据绑定时 user_verified=true 且本次断言也带 UV,任一缺失按 passkey_login_invalid 统一拒绝并记 auth.passkey_uv_rejected 审计。顺带修掉一个真实缺陷:WebAuthnCredentials 没把存储的 BE/BS 标志交给 go-webauthn,而 v0.17 会拒绝 BE 与存储不一致的断言,云同步 passkey(iCloud 钥匙串、Google 密码管理器)此前能注册、登不进。测试:virtualwebauthn 的 BE=1 认证器走两种登录入口(修复前红),三入口 × 三种缺 UV 情形;变异验证全部击杀。