doc: General security considerations for WebAuthn implementations
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 25/100
- issue の種類
- ドキュメント
- 明瞭さ
- 説明が足りない
- 活発さ
- 停滞
- 技術スタック
- javascript
調査の方向性
ファイル、テスト、エントリーポイントは指定されていません。まず、リポジトリ構成を確認して、文書化のための既存の場所を特定し、WebAuthn の実装を確認してから、これらの検討事項を範囲の明確なガイドに絞り込んでください。セキュリティに関するガイダンスが焦点を絞ったものになり、技術的なレビューを受け、ユーザーが見つけられる場所に統合されれば完了です。
索引モデルが issue の本文から書いたものです。
説明
The major security considerations
- signature verification
- challenge
- signCount
- userHandle
- Credential IDs
- Relying Party (domain)
- etc
Signature Verification
You must verify signatures. You cannot rely on the challenge alone.
- you must store the PublicKey by Credential ID (1) on Registration (2)
- (1) a.k.a.
.id,.rawId,response.authenticator.attestedCredential.credentialId - (2) a.k.a. device attestation,
webauthn.create
- (1) a.k.a.
- you must retrieve the PublicKey by Credential ID or Challenge on Authentication (3)
- (3) a.k.a. attestation,
webauthn.get
- (3) a.k.a. attestation,
- the WebAuthn (COSE) signature is in ASN.1 format, but WebCrypto requires it as p1363
(i.e. if you use WebCrypto in Node or Bun or Deno) attToBeSignedis the concatenation ofauthDataand the sha256 hash ofclientData
challenge
- you must generate the challenge server side
otherwise an attacker with device access could generate many signed challenges and use them in the future - DO NOT verify the signature alone, you MUST VERIFY the challenge
otherwise an attacker who gains access to the device can possibly create lots and lots of authentications and use them on future dates.
Sign Count
Sign count mitigates hardware cloning (e.g. YubiKey) and out-of-sync / offline / system-time-faked / cloned cloud authenticators (e.g. Apple iCloud Keychain).
if signCount > 0 then you should track the sign count and make sure that each new sign count is ALWAYS greater than the previous one (savedCount = newCount; db.save();
Only save the new signCount AFTER successful signature verification - otherwise an attacker can present a very high signCount, have it saved, and then lock the user out of their account.
userHandle
Don't send userHandle to the server. It's a misnomer. It's actually arbitrary user data. It can be used to store a local encryption key, for example.
Keep it secret. Keep it safe. Keep it client-side.
Note: in at least one place it's referred to as "id". This is incorrect. The "id" is the "credential id" and the remote user id is "user.name".
See also: https://github.com/mylofi/local-data-lock/issues/7
Credential IDs
bottom line: rate limit the retrieval of credential ids by ip address or other means so that an attacker can't just scan email addresses, and don't include any metadata such as created_at or user agent, etc with the credential ids you return
These are more used to identify the Authenticator than the specific Credential.
If you fail to provide these on new Passkey registration, you could easily permanently delete and replace an existing Passkey (i.e. iCloud only allows one Passkey per domain and will delete rather than add).
Since they are required before the user is authenticated in order to authenticate the user, they are essentially public values.
However, they also leak a small amount of statistical information about the user - the format of the ID may fingerprint which device or service is being used (by length, character distribution or prefix or suffix). Also, they show how many authenticators a user has.
So there's a bit of a catch 22:
- asking the user to try to authenticate and then register on failure is cumbersome and annoying
- if the user has cleared out their browser application cache or is on a different computer, you don't know if they have an authenticator (i.e. "silent" authentication doesn't actually work in practice)
- if you request the credential ids by email address, there's a small amount of info that an attacker can farm by looking up these ids in your system by email or whatever - and you obviously can't mask them otherwise you can't use them
Relying Party
In theory you should check that the domain or domain hash matches (rp.id / rpid / relying party / rpidhash) matches, but in practice, this doesn't actually matter because only a malicious device or browser plugin would be sharing your private key between accounts internally, at which point you've got other problems.
Authenticator devices or services or plugins that you can get from legitimate vendors (Apple, Yubico, Microsoft, Android, Lastpass, etc), all create pairwise Credential IDs - meaning that the ID has a unique constraint across domain and user id user accounts - so you're not going to get an "attestation" that's signed with the wrong domain.
The theoretical vulnerability requires that the device or service that uses a single Public Key and a single Credential ID to sign attestations for many domains, and that the user has given such as signed attestation to a malicious domain which then relays to your domain.
Also, the cross-origin spec, as of today (Oct 2024), does not exist. It's mentioned that there may be one in the future, and there's a cross-origin flag reserved for that use, but it's not spec'd or implemented.
etc
WebAuthn is chuck full of YAGNI.
There are so many different representations of similar data, so many things that will obviously never actually get implemented, and actual implementations lacking many things that we wish they would have (i.e. seamless background login, JSON).
Don't dig too deep. As Douglas Crockford warns: almost anything can be useful - just look at Rube Goldberg machines - but that doesn't mean it's a good idea.
Stick to the core things you need. Ignore the rest until the use case arises.
You could lose your life trying to build a framework that finds utility for every possible nook and cranny of the spec.
- 主要言語
- JavaScript
- スター
- 2
- フォーク
- 1
- PR マージ指標
- 30日以内にマージされた PR はありません
コントリビューションガイド
このリポジトリのコントリビューションガイドは索引されていません
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
BeyondCodeBootcamp/passkeys のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 25/100
-
難易度 3/5 1〜2日 初心者へのやさしさ 35/100
-
難易度 4/5 3〜5日 初心者へのやさしさ 25/100
-
難易度 4/5 3〜5日 初心者へのやさしさ 28/100
BeyondCodeBootcamp/passkeys#6 · コメント 1 件 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 25/100
BeyondCodeBootcamp/passkeys の issue をすべて見る
似ている issue
-
bug confirmed issue
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
open-webui/open-webui#30750 · コメント 1 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
Mend: dependency security vulnerability untriaged
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100