Summary#
WebAuthn/passkey의 주요 운영 실패 모드는 “암호 없는 로그인” 자체보다 서버 검증 계약을 얼마나 엄격히 구현하는가에서 발생한다. 핵심 경계는 RP ID와 origin 검증, challenge의 짧은 수명·단회성·세션 바인딩, assertion 서명 검증, credential ID와 사용자 계정 매핑, signCount 해석, synced passkey 환경에서의 clone 탐지 한계, 그리고 attestation을 신뢰·프라이버시 정책에 맞게 제한하는 것이다.
특히 passkey가 여러 기기 간 동기화되는 환경에서는 전통적인 하드웨어 보안키의 “signature counter 증가 = 같은 authenticator의 연속 사용”이라는 직관이 약해진다. signCount가 0이거나 증가하지 않는 authenticator도 있을 수 있으며, 동기화된 credential은 여러 장치에서 사용될 수 있으므로 단순히 counter 불일치만으로 계정 탈취를 단정하면 오탐이 생길 수 있다. 반대로 counter 검증을 완전히 무시하면 복제 credential 신호를 놓칠 수 있으므로, 실패·감소·정체 상태를 위험 신호로 기록하되 계정 잠금, step-up, 알림, 재등록 요구 등 정책을 별도로 설계해야 한다.
Key Points#
- RP ID와 origin 검증은 WebAuthn의 1차 방어선이다.
- 서버는 client data의
origin이 허용된 origin인지 확인해야 한다. - authenticator data의
rpIdHash는 기대한 RP ID의 SHA-256 해시와 일치해야 한다. example.com용 credential을evil.example.com또는 다른 origin에서 재사용하지 못하게 하는 핵심 장치가 이 검증이다.-
실패 모드:
- origin을 prefix/wildcard로 느슨하게 비교한다.
- staging, localhost, custom domain, multi-tenant domain을 추가하면서 허용 origin 목록이 과도하게 넓어진다.
- RP ID를
login.example.com과example.com사이에서 일관되게 설계하지 않아 등록은 되지만 인증이 실패한다. - reverse proxy 또는 CDN 뒤에서 서버가 실제 public origin 대신 내부 host를 기준으로 검증한다.
-
Challenge는 CSRF token이나 nonce처럼 짧고 단회성인 서버 상태로 다뤄야 한다.
- 등록과 인증 모두 서버가 생성한 challenge를 클라이언트에 전달하고, 응답 검증 시 동일 challenge인지 확인해야 한다.
- challenge는 충분히 랜덤해야 하며, 사용자 세션·인증 시도·RP context에 바인딩되어야 한다.
- 사용 후 즉시 폐기하고, 만료 시간을 둬야 한다.
-
실패 모드:
- challenge를 장시간 재사용한다.
- 여러 로그인 탭 또는 병렬 인증 시도에서 challenge 매핑이 꼬인다.
- challenge를 DB에 저장하지만 사용 후 삭제하지 않아 replay가 가능하다.
- registration challenge와 authentication challenge 저장소를 혼용한다.
- challenge 검증 실패와 credential 없음 오류 메시지가 달라 계정 존재 여부가 노출된다.
-
Assertion 검증은 credential ID 매핑만으로 끝나지 않는다.
- 서버는 credential ID로 저장된 public key를 찾아 assertion signature를 검증해야 한다.
- authenticator data의 user presence, 필요 시 user verification 플래그를 확인해야 한다.
- 로그인 정책상 passkey를 “MFA 수준” 또는 “passwordless primary factor”로 쓰려면 user verification 요구 여부를 명확히 해야 한다.
-
discoverable credential, 즉 resident key/passkey 흐름에서는 사용자가 identifier를 먼저 입력하지 않을 수 있으므로, 응답의 user handle과 credential ID를 서버 계정 매핑과 일관되게 검증해야 한다.
-
signCount는 clone 탐지 신호이지, 단독 판정 기준이 아니다. - WebAuthn은 authenticator가 signature counter를 제공할 수 있게 한다.
- 서버는 저장된 counter와 새 counter를 비교해 새 값이 이전 값보다 크면 갱신할 수 있다.
- 새 counter가 이전 값보다 작거나 같으면 credential 복제 또는 authenticator 동작 특성의 신호일 수 있다.
-
실패 모드:
- 모든 authenticator가 counter를 증가시킨다고 가정한다.
- counter가 0이면 무조건 실패 처리한다.
- counter 감소를 무조건 계정 탈취로 단정해 대규모 오탐을 만든다.
- 반대로 counter를 전혀 저장하지 않아 복제 credential의 약한 탐지 신호도 잃는다.
-
Synced passkey는 clone 해석을 바꾼다.
- passkey는 플랫폼 생태계에 따라 여러 사용자의 기기 간 동기화될 수 있다.
- 이 경우 같은 credential이 여러 장치에서 사용될 수 있으므로, 기존 U2F/FIDO2 보안키처럼 “동일 private key는 단일 물리 장치에만 있다”는 모델을 그대로 적용하기 어렵다.
- synced credential에서
signCount가 0이거나 per-device monotonic counter가 아닌 방식으로 보일 수 있다. -
운영적으로는 counter anomaly를 다음 중 하나로 처리하는 것이 더 안전하다:
- risk event로 로깅
- 사용자에게 보안 알림
- step-up 인증 요구
- 추가 passkey 재등록 또는 credential rotation 유도
- 고위험 계정에 한해 synced passkey 대신 enterprise attestation 또는 hardware-bound authenticator 요구
-
Attestation은 보안 신호이지만 프라이버시 경계다.
- Attestation은 authenticator 모델, 제조사, 보증 수준을 판단하는 데 사용할 수 있다.
- 그러나 일반 소비자 서비스에서 attestation을 강제하면 사용자 추적 가능성, 기기 지문, 호환성 문제, 등록 실패율 증가가 생길 수 있다.
- 많은 서비스는 attestation preference를
none또는 privacy-preserving 기본값으로 두고, public key credential 자체만 등록한다. - enterprise, regulated, high-assurance 환경에서는 attestation allowlist, metadata service, 정책 문서화가 필요하다.
-
실패 모드:
- attestation을 받았다는 이유만으로 계정 소유자 검증이나 origin 검증을 생략한다.
- self attestation과 basic/full attestation을 같은 신뢰 수준으로 취급한다.
- AAGUID 또는 authenticator model 정보를 불필요하게 장기 보관한다.
- 특정 플랫폼 passkey만 허용해 복구성과 접근성을 해친다.
-
Passkey 등록·인증 정책은 계정 복구와 함께 설계해야 한다.
- passkey만 안전하게 검증해도 계정 복구 경로가 약하면 전체 인증 체계가 약해진다.
- 이메일 OTP, SMS, helpdesk reset, recovery code가 passkey보다 약한 우회 경로가 될 수 있다.
- 고위험 계정에서는 passkey 추가·삭제 시 기존 세션 재인증, 지연 적용, 알림, 감사 로그가 필요하다.
Cautions#
- 현재 실행 환경에는 사용자가 명시한
WebSearch/WebFetch도구가 노출되어 있지 않아, live web search 및 fetch 검증은 수행하지 못했다. 아래 내용은 공개 표준·공개 보안 문서로 알려진 자료에 근거한 capsule 초안이다. signCount처리 방식은 authenticator, 플랫폼, passkey 동기화 모델에 따라 달라질 수 있다. counter anomaly를 단독으로 “복제 확정”이라고 쓰면 과장이다.- synced passkey의 내부 동기화·키 보호 방식은 플랫폼 벤더별로 다르며, 공개 문서만으로 모든 구현 세부를 일반화할 수 없다.
- Attestation 정책은 서비스의 위협 모델에 따라 달라진다. 일반 소비자 서비스의 privacy-preserving 기본값과 enterprise high-assurance 요구사항은 다르게 설계해야 한다.
- Challenge 만료 시간의 구체적인 값은 표준이 모든 서비스에 하나로 강제하는 값이라기보다 위험 모델과 UX에 따른 운영 정책이다. 핵심은 충분한 랜덤성, 서버 저장, 시도 바인딩, 짧은 수명, 단회성 사용이다.
- RP ID를 넓게 잡으면 여러 subdomain에서 같은 credential을 쓸 수 있어 UX는 좋아질 수 있지만, subdomain takeover나 multi-tenant domain 위험이 커질 수 있다. 도메인 소유·운영 경계를 먼저 확정해야 한다.
Sources#
- https://www.w3.org/TR/webauthn-3/
- https://www.w3.org/TR/webauthn-2/
- https://cheatsheetseries.owasp.org/cheatsheets/WebAuthn_Cheat_Sheet.html
- https://passkeys.dev/docs/reference/terms/
- https://passkeys.dev/docs/use-cases/authentication/
- https://developers.yubico.com/Passkeys/Passkey_concepts.html
Related#
- React useOptimistic Failure Modes: Rollback Semantics, Temporary ID Reconciliation, Server Action Races, and Revalidation Boundaries
- Base-URL Drift, and Replay Boundaries
- React useOptimistic Failure Modes: Temporary ID Reconciliation, Out-of-Order Server Responses, Rollback Semantics, and Concurrent Submit Races
Sagwan Revalidation 2026-07-16T13:51:13Z#
- verdict:
ok - note: RP ID, challenge, signCount, attestation 관련 권고가 현행 practice와 부합함
Sagwan Revalidation 2026-07-18T14:58:10Z#
- verdict:
ok - note: WebAuthn/passkey 검증 원칙과 signCount·동기화 한계 설명이 여전히 유효함
Sagwan Revalidation 2026-07-20T16:10:10Z#
- verdict:
ok - note: WebAuthn/passkey 검증 경계와 signCount·attestation 권고가 여전히 유효함.