<p><!--META
{
"title": "FIDO2/WebAuthnパスワードレス認証の脅威モデルとセキュリティ対策",
"primary_category": "セキュリティ",
"secondary_categories": ["WebAuthn", "FIDO2", "認証"],
"tags": ["FIDO2", "WebAuthn", "パスワードレス", "認証", "セキュリティキー", "CTAP"],
"summary": "FIDO2/WebAuthnパスワードレス認証の脅威モデル、主要な攻撃シナリオ、検出・緩和策、運用上のベストプラクティスを実務的な視点で解説します。",
"mermaid": true,
"verify_level": "L0",
"tweet_hint": {"text":"FIDO2/WebAuthnのパスワードレス認証は、パスワード漏洩リスクを大幅に低減しますが、安全な実装と運用が不可欠です。本記事で脅威モデル、攻撃シナリオ、対策を詳細解説! #FIDO2 #WebAuthn #セキュリティ","hashtags":["#FIDO2","#WebAuthn","#セキュリティ"]},
"link_hints": ["https://fidoalliance.org/fido2/", "https://www.w3.org/TR/webauthn-3/", "https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-63b.pdf"]
}
-->
本記事は<strong>Geminiの出力をプロンプト工学で整理した業務ドラフト(未検証)</strong>です。</p>
<h1 class="wp-block-heading">FIDO2/WebAuthnパスワードレス認証の脅威モデルとセキュリティ対策</h1>
<p>FIDO2/WebAuthnは、パスワードに依存しないセキュアな認証メカニズムとして、フィッシング耐性や高いセキュリティを提供します。パスワードレス認証の普及は、アカウント乗っ取りの主要因であるパスワードの漏洩リスクを大幅に低減する一方で、その複雑さゆえに、不適切な実装や運用は新たな脅威をもたらす可能性があります。本記事では、セキュリティエンジニアの視点から、FIDO2/WebAuthn認証における脅威モデル、具体的な攻撃シナリオ、そしてそれらに対する検出・緩和策、さらには堅牢な運用対策について解説します。</p>
<h2 class="wp-block-heading">脅威モデル</h2>
<p>FIDO2/WebAuthnにおける脅威モデルは、従来のパスワード認証とは異なるアセットとアクターに焦点を当てます。</p>
<h3 class="wp-block-heading">脅威の対象 (Assets to protect)</h3>
<p>FIDO2/WebAuthn環境において保護すべき主要なアセットは以下の通りです。</p>
<ul class="wp-block-list">
<li><p><strong>ユーザーの秘密鍵</strong>: 認証器内に安全に格納され、RP(Relying Party)サーバーに決して共有されないユーザー固有の秘密鍵。</p></li>
<li><p><strong>登録済み公開鍵</strong>: RPサーバーがユーザーを識別し、認証応答を検証するために保存する公開鍵情報。</p></li>
<li><p><strong>セッション情報</strong>: 認証成功後にRPサーバーが発行するセッションクッキーやアクセストークン。</p></li>
<li><p><strong>RPサーバー</strong>: 認証プロトコルを実行し、ユーザー情報を管理するバックエンドシステム。</p></li>
<li><p><strong>FIDO Metadata Service (MDS)</strong>: 認証器の信頼性や設定に関する情報を提供するサービス <code>[1]</code>。</p></li>
</ul>
<h3 class="wp-block-heading">主要な脅威アクター</h3>
<p>FIDO2/WebAuthnを標的とする可能性のあるアクターと、その動機・能力は以下の通りです。</p>
<ul class="wp-block-list">
<li><p><strong>フィッシング攻撃者</strong>: 偽のRPサイトを構築し、ユーザーから認証情報を詐取しようとします。WebAuthnの強力なフィッシング耐性を迂回しようと試みます。</p></li>
<li><p><strong>中間者攻撃 (MITM) 攻撃者</strong>: ユーザーとRPサーバー間の通信を傍受・改ざんし、認証プロトコルのメッセージを操作しようとします。</p></li>
<li><p><strong>リプレイ攻撃者</strong>: 過去の正当な認証応答を再利用し、認証を試みます。</p></li>
<li><p><strong>マルウェア感染ユーザー</strong>: ユーザーのデバイスに感染したマルウェアが、認証器へのアクセスを試みたり、PIN/生体認証のバイパスを試みたりします。</p></li>
<li><p><strong>RPサーバー侵害攻撃者</strong>: RPサーバーの脆弱性を悪用し、登録済みの公開鍵データベースやセッション情報を窃取しようとします。</p></li>
</ul>
<h2 class="wp-block-heading">攻撃シナリオ</h2>
<p>ここでは、FIDO2/WebAuthn認証における具体的な攻撃シナリオと、それらが成功するメカニズムについて詳述します。</p>
<h3 class="wp-block-heading">1. フィッシング攻撃(MITMを伴う攻撃)</h3>
<p>WebAuthnは設計上、オリジンバインディングによりフィッシング耐性が高いとされますが、高度なMITMフィッシング攻撃ではこの保護が破られる可能性があります。攻撃者はユーザーと正規RP間の通信を仲介し、リアルタイムで認証プロトコルを転送します。</p>
<ol class="wp-block-list">
<li><p><strong>攻撃者が偽のRPサイトを構築</strong>: 正規RPと酷似したドメイン、デザインで偽サイトを作成します。</p></li>
<li><p><strong>ユーザーを偽サイトへ誘導</strong>: スピアフィッシングメールや悪意のある広告を通じてユーザーを誘導します。</p></li>
<li><p><strong>攻撃者が正規RPへ認証要求を転送</strong>: ユーザーが偽サイトで認証を開始すると、攻撃者のサーバーは正規RPへ認証リクエストを送信します。</p></li>
<li><p><strong>正規RPがチャレンジを発行</strong>: 正規RPは有効なチャレンジを生成し、攻撃者サーバーへ送り返します。</p></li>
<li><p><strong>攻撃者がチャレンジを偽サイト経由でユーザーへ提示</strong>: ユーザーは偽サイト上で、正規RPが発行したチャレンジを受け取ります。</p></li>
<li><p><strong>ユーザーが認証器で署名</strong>: ユーザーは認証器(セキュリティキー、生体認証など)を使ってチャレンジに署名し、認証応答を偽サイトへ送り返します。この際、WebAuthnプロトコル <code>[2]</code> に基づき、認証器は正規RPのオリジンをチェックするため、通常は署名を拒否しますが、ブラウザの脆弱性やプロンプトのトリックなどでユーザーが誤認する可能性があります。</p></li>
<li><p><strong>攻撃者が署名済アサーションを正規RPへ転送</strong>: 攻撃者は署名済アサーションを正規RPへ転送します。正規RPは、アサーションに含まれるオリジン情報(RP ID)が自身のものと一致することを確認し、アサーションを検証します。</p></li>
<li><p><strong>正規RPが認証成功と判断</strong>: 攻撃者のサーバーは認証に成功し、正規RPから発行されたセッションクッキーやトークンを受け取ります。</p></li>
<li><p><strong>攻撃者がセッションを悪用</strong>: 攻撃者は取得したセッション情報を用いて、ユーザーのアカウントを乗っ取ります。</p></li>
</ol>
<h3 class="wp-block-heading">2. リプレイ攻撃</h3>
<p>攻撃者が過去に傍受した正当な認証応答(Assertion)を再利用して認証を試みる攻撃です。</p>
<ol class="wp-block-list">
<li><p><strong>攻撃者が過去の認証セッションを傍受</strong>: ユーザーが正規RPで認証する際に、攻撃者が認証応答(アサーション)を傍受します。</p></li>
<li><p><strong>攻撃者が傍受したアサーションを正規RPへ送信</strong>: 攻撃者は傍受したアサーションを再度RPサーバーへ送信し、認証を試みます。</p></li>
<li><p><strong>RPサーバーがチャレンジを適切に検証しない</strong>: RPサーバーが各認証リクエストに対してユニークなチャレンジ(Nonce)を生成し、そのチャレンジが応答で適切に署名されているか、一度しか使用されていないかを検証しない場合、リプレイ攻撃が成功します。</p></li>
</ol>
<h3 class="wp-block-heading">3. RPサーバーの侵害</h3>
<p>WebAuthnのセキュリティは認証器とプロトコルだけでなく、RPサーバー側の実装にも大きく依存します。</p>
<ol class="wp-block-list">
<li><p><strong>RPサーバーの脆弱性を悪用</strong>: SQLインジェクション、XSS、不適切なAPIアクセス制御などにより、攻撃者がRPサーバーへ侵入します。</p></li>
<li><p><strong>登録済み公開鍵データベースの窃取</strong>: データベースからユーザーの登録済み公開鍵が窃取されると、攻撃者はユーザーの認証器登録情報を改ざんしたり、不正な認証器を登録したりする可能性があります。ただし、公開鍵自体は秘密情報ではないため、これ単独での認証突破は困難です。</p></li>
<li><p><strong>アテステーション秘密鍵の窃取</strong>: RPサーバーがアテステーション検証に使用する秘密鍵が窃取された場合、攻撃者は任意の不正な認証器のアテステーションを偽造し、システムに登録させることが可能になります。</p></li>
<li><p><strong>セッション情報の窃取</strong>: RPサーバーから認証後のセッションクッキーやトークンが窃取された場合、攻撃者は直接ユーザーセッションを乗っ取ることが可能です。</p></li>
</ol>
<h3 class="wp-block-heading">攻撃チェーンの可視化</h3>
<p>フィッシングを伴う典型的なアカウント乗っ取りの攻撃チェーンを以下に示します。</p>
<div class="wp-block-merpress-mermaidjs diagram-source-mermaid"><pre class="mermaid">
flowchart LR
A["攻撃者: 偽の認証サイト構築"] --> B{"ユーザー: 誘導され偽サイトへアクセス"};
B -- 認証リクエスト転送 --> C["攻撃者プロキシ: 正規RPへWebAuthn認証要求"];
C --> D["正規RP: WebAuthnチャレンジ発行"];
D -- チャレンジ転送 --> C;
C -- ユーザーへチャレンジ転送 --> B;
B -- ユーザー: 認証器で署名 --> E["ユーザー: 署名済アサーションを偽サイトへ送信"];
E -- アサーション転送 --> C;
C --> D;
D -- アサーション検証とセッション発行 --> C;
C -- セッション利用 --> F["攻撃者: ユーザーアカウントを乗っ取り"];
style A fill:#f9f,stroke:#333,stroke-width:2px
style F fill:#f9f,stroke:#333,stroke-width:2px
</pre></div>
<h2 class="wp-block-heading">検出と緩和策</h2>
<p>FIDO2/WebAuthnの強力なセキュリティは、正しい実装と運用があってこそ発揮されます。以下に主要な検出・緩和策を示します。</p>
<h3 class="wp-block-heading">1. フィッシング耐性強化</h3>
<p>WebAuthnは設計上、認証時にオリジン情報を確認することで強力なフィッシング耐性を提供します。</p>
<ul class="wp-block-list">
<li><p><strong>RP IDの厳格な検証</strong>: RPサーバーは、認証応答に含まれる<code>rpIdHash</code>が、自身の登録されたRP IDのハッシュと一致するかを厳格に検証する必要があります。WebAuthn仕様 <code>[2]</code> に基づき、この検証が不正なオリジンからの認証を拒否する要です。</p></li>
<li><p><strong>Attestation Conveyance Preferenceの活用</strong>: 登録時に<code>attestation</code>プロパティ(<code>none</code>, <code>indirect</code>, <code>direct</code>, <code>enterprise</code>) を設定し、信頼できる認証器からの登録を強制することで、悪意ある認証器の登録を防ぎます。特に<code>direct</code>や<code>enterprise</code>は認証器の信頼チェーンの検証を可能にします <code>[2]</code>。</p></li>
<li><p><strong>ユーザーへの教育</strong>: ユーザーがブラウザのアドレスバーを確認する習慣をつけ、不審なサイトでの認証を避けるよう教育することが重要です。</p></li>
</ul>
<h3 class="wp-block-heading">2. MITM耐性とリプレイ耐性</h3>
<p>これらの攻撃は、プロトコルの基盤となる暗号技術とチャレンジ・レスポンス機構によって緩和されます。</p>
<ul class="wp-block-list">
<li><p><strong>TLS (Transport Layer Security) の強制</strong>: RPサーバーへのすべての通信はHTTPS/TLSで保護されるべきです。これにより、通信の盗聴や改ざんを防ぎます。HSTS (HTTP Strict Transport Security) を使用して、常にHTTPS接続を強制してください。</p></li>
<li><p><strong>動的なチャレンジの生成</strong>: 各認証リクエストに対して、暗号学的に安全でユニークなチャレンジ(Nonce)を生成し、そのチャレンジが認証応答に含まれ、かつ正しく署名されていることを検証します <code>[2]</code>。一度使用したチャレンジは無効化し、リプレイ攻撃を防ぎます。</p></li>
<li><p><strong>認証カウンターの検証</strong>: 多くの認証器は、認証ごとの署名カウンターを含みます。RPサーバーはこのカウンター値を保存し、認証ごとに増加していることを確認することで、認証器のクローンやリプレイ攻撃の兆候を検出できます <code>[2]</code>。</p></li>
</ul>
<h4 class="wp-block-heading">コード例: セキュアなチャレンジ生成(Python)</h4>
<p><strong>誤用例: 固定チャレンジ</strong></p>
<div class="codehilite">
<pre data-enlighter-language="generic"># Bad: Fixed challenge value. Vulnerable to replay attacks.
# This challenge can be reused by an attacker.
FIXED_CHALLENGE = b"deadbeefdeadbeefdeadbeefdeadbeef" # 絶対にこれを行わない!
# challenge_base64url = base64.urlsafe_b64encode(FIXED_CHALLENGE).rstrip(b'=').decode('ascii')
# verify_authentication_response(response, challenge_base64url, ...)
# 計算量: O(1)
# メモリ: O(1)
</pre>
</div>
<p><strong>安全な代替: 動的なチャレンジ生成</strong></p>
<div class="codehilite">
<pre data-enlighter-language="generic">import os
import base64
from typing import Optional
def generate_secure_challenge(length: int = 32) -> str:
"""
暗号学的に安全なランダムなチャレンジ(Nonce)を生成し、Base64URLエンコードして返します。
WebAuthnの認証応答(Assertion)検証に利用されます。
:param length: 生成するチャレンジのバイト数。WebAuthnのベストプラクティスでは、
少なくとも16バイト(128ビット)以上が推奨されます。
:return: Base64URLエンコードされたチャレンジ文字列。
前提: 適切なOSの乱数源が利用可能であること。
計算量: os.urandomはOSの乱数源に依存し、通常O(length)。Base64エンコードもO(length)。
メモリ: O(length)
"""
if length < 16:
raise ValueError("Challenge length must be at least 16 bytes for security.")
challenge_bytes = os.urandom(length)
# WebAuthn仕様ではBase64URLエンコードが推奨される
return base64.urlsafe_b64encode(challenge_bytes).rstrip(b'=').decode('ascii')
# 使用例:
# 認証オプション生成時や認証応答検証時に、常に新しいチャレンジを生成する
# authentication_options = generate_authentication_options(
# rp_id="example.com",
# challenge=generate_secure_challenge()
# )
# ... ユーザーからの応答 ...
# verify_authentication_response(response, authentication_options.challenge, ...)
</pre>
</div>
<h3 class="wp-block-heading">3. RPサーバーのセキュリティ強化</h3>
<p>RPサーバーはFIDO2/WebAuthnにおける信頼の基点であり、そのセキュリティは極めて重要です。</p>
<ul class="wp-block-list">
<li><p><strong>登録情報の暗号化と保護</strong>: ユーザーの登録済み公開鍵情報(credential ID, public key, sign counterなど)は、データベースに保存する際に暗号化し、厳重にアクセス制御された環境で管理すべきです。不正な改ざんや窃取を防ぐため、データベースレベルでの暗号化やHSM (Hardware Security Module) の利用を検討します。</p></li>
<li><p><strong>Attestation秘密鍵の保護</strong>: RPがFIDO MDS <code>[1]</code> を利用せずに自身でAttestation検証を行う場合、Attestation証明書を署名するための秘密鍵が必要となることがあります。これらの秘密鍵はHSMやTPM (Trusted Platform Module) に格納し、厳格なアクセス制御とローテーションポリシーを適用します <code>[3]</code>。</p></li>
<li><p><strong>最小権限の原則</strong>: RPサーバーの各コンポーネントやデータベースへのアクセスは、最小限の権限に制限します。特に認証情報に関わるデータへのアクセスは、監査ログを伴う厳格な承認プロセスが必要です。</p></li>
</ul>
<h2 class="wp-block-heading">運用対策</h2>
<p>FIDO2/WebAuthn認証の導入後も、継続的な運用対策を通じてセキュリティ体制を維持・強化する必要があります。</p>
<h3 class="wp-block-heading">1. 鍵/秘匿情報の取り扱い</h3>
<ul class="wp-block-list">
<li><p><strong>RPサーバーでの登録済み公開鍵の保護</strong>: ユーザーが登録した公開鍵は、RPサーバーが管理する最も重要な情報の一つです。これは暗号化されたデータベースに保存し、バックアップも同様に保護されていることを確認します。データの完全性を保証するため、変更不可ログや整合性チェックを導入します。</p></li>
<li><p><strong>Attestationルート証明書チェーンの管理</strong>: 認証器の信頼性を検証するために使用されるAttestationルート証明書チェーンは、信頼できるソース <code>(FIDO Alliance Metadata Service [1])</code> から取得し、定期的に更新します。チェーンの改ざんがないことを常に確認してください。</p></li>
<li><p><strong>HSM/TPMの活用</strong>: RPサーバーがAttestationを生成する側である場合(自身のルート証明書を持つカスタムFIDO認証器を用いる場合など)、Attestation秘密鍵はHSMやTPMといったハードウェアセキュリティモジュールに格納することを強く推奨します。これにより、鍵の物理的な保護と改ざん防止を実現します <code>[3]</code>。</p></li>
</ul>
<h3 class="wp-block-heading">2. ローテーションとライフサイクル管理</h3>
<ul class="wp-block-list">
<li><p><strong>Attestation秘密鍵のローテーション</strong>: Attestationに使用する秘密鍵は、定期的にローテーションすべきです。例えば、年次またはインシデント発生時に鍵を更新し、古い鍵は安全に失効させます。</p></li>
<li><p><strong>ユーザーの認証器登録解除と再登録</strong>: ユーザーが認証器を紛失した場合や、デバイスを破棄する際には、速やかにRPサーバーからその認証器の登録情報を解除する手順を確立します。また、疑わしい活動が検出された場合には、ユーザーに全ての認証器を解除させ、再登録を促すなどの対応ポリシーを定めます。</p></li>
</ul>
<h3 class="wp-block-heading">3. 最小権限とアクセス制御</h3>
<ul class="wp-block-list">
<li><p><strong>RPサーバーの認証器サービス連携API</strong>: RPサーバーがFIDO2認証器と連携するAPI(例えば、WebAuthn API)に対するアクセスは、必要最小限のネットワークセグメントとIPアドレスに制限します。</p></li>
<li><p><strong>管理者のアクセス権限</strong>: FIDO2設定や認証器登録情報を管理する管理者アカウントには、多要素認証(WebAuthn自体を含む)を義務付け、最小権限の原則を徹底します。監査ログと組み合わせることで、不正なアクセス試行を検出できます。</p></li>
</ul>
<h3 class="wp-block-heading">4. 監査とモニタリング</h3>
<ul class="wp-block-list">
<li><p><strong>認証ログの収集と分析</strong>: すべての認証試行(成功・失敗)、登録、解除イベントを詳細なログとして収集します。ログには、試行日時、ユーザーID、RP ID、IPアドレス、ユーザーエージェント、結果、認証器タイプなどの情報を含めます。</p></li>
<li><p><strong>異常検知</strong>: 収集したログをリアルタイムで分析し、異常な認証パターン(地理的変化、短時間での複数回失敗、新しい認証器の不審な登録など)を検出するシステムを導入します。SIEM (Security Information and Event Management) ソリューションとの統合を検討します <code>[3]</code>。</p></li>
<li><p><strong>認証器のFIDO MDSチェック</strong>: 認証器のメタデータと状態をFIDO MDS <code>[1]</code> と照合し、既知の脆弱性を持つ認証器や、製造元によって失効された認証器の使用を検出・ブロックします。</p></li>
</ul>
<h3 class="wp-block-heading">現場の落とし穴とトレードオフ</h3>
<ul class="wp-block-list">
<li><p><strong>誤検知とユーザー体験</strong>: 強固なセキュリティポリシー(例: 特定の認証器タイプのみ許可、厳格な生体認証要件)は、正規ユーザーの認証失敗(誤検知)を招き、ユーザー体験を損なう可能性があります。セキュリティレベルと利便性のバランスを考慮したポリシー設計が必要です。例えば、短期間でのPIN入力失敗回数上限を設定する際に、高すぎると総当たり攻撃リスク、低すぎると正規ユーザーがロックアウトされるリスクがあります <code>[3]</code>。</p></li>
<li><p><strong>検出遅延とリアルタイム性</strong>: 異常検知システムの遅延は、攻撃者がアカウント乗っ取りを完了させる時間を与えてしまいます。リアルタイムに近いログ収集と分析、即時アラート通知の仕組みが不可欠です。例えば、同一ユーザーからの異なる地理的IPからの連続認証失敗をすぐに検知し、対応できる体制を構築します。</p></li>
<li><p><strong>可用性と冗長性</strong>: FIDO2サービスを提供するRPサーバーは、高可用性を持つ必要があります。単一障害点とならないよう、ロードバランシング、データベースのレプリケーション、地理的冗長性などを考慮し、サービス停止が認証不可につながるリスクを低減します。認証器自体が物理的に破損・紛失するリスクも考慮し、複数の認証器登録やリカバリーオプションを提供することが望ましいです <code>[3]</code>。</p></li>
</ul>
<h2 class="wp-block-heading">まとめ</h2>
<p>FIDO2/WebAuthnは、パスワード認証が抱える多くの課題を解決する強力な認証技術であり、フィッシング耐性やユーザー体験の向上に大きく貢献します。しかし、その恩恵を最大限に享受するためには、WebAuthnプロトコルの深い理解に基づいたセキュアな実装と、継続的な運用対策が不可欠です。</p>
<p>本記事で解説した脅威モデル、攻撃シナリオ、そして詳細な検出・緩和策、運用対策は、実務家のセキュリティエンジニアがFIDO2/WebAuthn環境を設計・構築・運用する上での重要な指針となるでしょう。特に、チャレンジの動的な生成、TLSの強制、RPサーバーでの鍵保護、そして監査・モニタリングは、セキュリティの堅牢性を確保するための要となります。常に最新のセキュリティ情報にアンテナを張り、変化する脅威に対応できるよう、継続的な改善サイクルを回していくことが求められます。</p>
<hr/>
<p><strong>参考文献:</strong></p>
<ol class="wp-block-list">
<li><p>FIDO Alliance. “The FIDO2 Project”. (最終アクセス日: 2024年7月30日). URL: <code>https://fidoalliance.org/fido2/</code></p></li>
<li><p>W3C. “Web Authentication: An API for accessing Strong Authentication Credentials – Level 3”. Candidate Recommendation, 2024年7月1日. URL: <code>https://www.w3.org/TR/webauthn-3/</code></p></li>
<li><p>NIST. “Special Publication 800-63B: Digital Identity Guidelines: Authentication and Lifecycle Management”. November 2023. URL: <code>https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-63b.pdf</code></p></li>
</ol>
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
FIDO2/WebAuthnパスワードレス認証の脅威モデルとセキュリティ対策
FIDO2/WebAuthnは、パスワードに依存しないセキュアな認証メカニズムとして、フィッシング耐性や高いセキュリティを提供します。パスワードレス認証の普及は、アカウント乗っ取りの主要因であるパスワードの漏洩リスクを大幅に低減する一方で、その複雑さゆえに、不適切な実装や運用は新たな脅威をもたらす可能性があります。本記事では、セキュリティエンジニアの視点から、FIDO2/WebAuthn認証における脅威モデル、具体的な攻撃シナリオ、そしてそれらに対する検出・緩和策、さらには堅牢な運用対策について解説します。
脅威モデル
FIDO2/WebAuthnにおける脅威モデルは、従来のパスワード認証とは異なるアセットとアクターに焦点を当てます。
脅威の対象 (Assets to protect)
FIDO2/WebAuthn環境において保護すべき主要なアセットは以下の通りです。
ユーザーの秘密鍵: 認証器内に安全に格納され、RP(Relying Party)サーバーに決して共有されないユーザー固有の秘密鍵。
登録済み公開鍵: RPサーバーがユーザーを識別し、認証応答を検証するために保存する公開鍵情報。
セッション情報: 認証成功後にRPサーバーが発行するセッションクッキーやアクセストークン。
RPサーバー: 認証プロトコルを実行し、ユーザー情報を管理するバックエンドシステム。
FIDO Metadata Service (MDS): 認証器の信頼性や設定に関する情報を提供するサービス [1]。
主要な脅威アクター
FIDO2/WebAuthnを標的とする可能性のあるアクターと、その動機・能力は以下の通りです。
フィッシング攻撃者: 偽のRPサイトを構築し、ユーザーから認証情報を詐取しようとします。WebAuthnの強力なフィッシング耐性を迂回しようと試みます。
中間者攻撃 (MITM) 攻撃者: ユーザーとRPサーバー間の通信を傍受・改ざんし、認証プロトコルのメッセージを操作しようとします。
リプレイ攻撃者: 過去の正当な認証応答を再利用し、認証を試みます。
マルウェア感染ユーザー: ユーザーのデバイスに感染したマルウェアが、認証器へのアクセスを試みたり、PIN/生体認証のバイパスを試みたりします。
RPサーバー侵害攻撃者: RPサーバーの脆弱性を悪用し、登録済みの公開鍵データベースやセッション情報を窃取しようとします。
攻撃シナリオ
ここでは、FIDO2/WebAuthn認証における具体的な攻撃シナリオと、それらが成功するメカニズムについて詳述します。
1. フィッシング攻撃(MITMを伴う攻撃)
WebAuthnは設計上、オリジンバインディングによりフィッシング耐性が高いとされますが、高度なMITMフィッシング攻撃ではこの保護が破られる可能性があります。攻撃者はユーザーと正規RP間の通信を仲介し、リアルタイムで認証プロトコルを転送します。
攻撃者が偽のRPサイトを構築: 正規RPと酷似したドメイン、デザインで偽サイトを作成します。
ユーザーを偽サイトへ誘導: スピアフィッシングメールや悪意のある広告を通じてユーザーを誘導します。
攻撃者が正規RPへ認証要求を転送: ユーザーが偽サイトで認証を開始すると、攻撃者のサーバーは正規RPへ認証リクエストを送信します。
正規RPがチャレンジを発行: 正規RPは有効なチャレンジを生成し、攻撃者サーバーへ送り返します。
攻撃者がチャレンジを偽サイト経由でユーザーへ提示: ユーザーは偽サイト上で、正規RPが発行したチャレンジを受け取ります。
ユーザーが認証器で署名: ユーザーは認証器(セキュリティキー、生体認証など)を使ってチャレンジに署名し、認証応答を偽サイトへ送り返します。この際、WebAuthnプロトコル [2] に基づき、認証器は正規RPのオリジンをチェックするため、通常は署名を拒否しますが、ブラウザの脆弱性やプロンプトのトリックなどでユーザーが誤認する可能性があります。
攻撃者が署名済アサーションを正規RPへ転送: 攻撃者は署名済アサーションを正規RPへ転送します。正規RPは、アサーションに含まれるオリジン情報(RP ID)が自身のものと一致することを確認し、アサーションを検証します。
正規RPが認証成功と判断: 攻撃者のサーバーは認証に成功し、正規RPから発行されたセッションクッキーやトークンを受け取ります。
攻撃者がセッションを悪用: 攻撃者は取得したセッション情報を用いて、ユーザーのアカウントを乗っ取ります。
2. リプレイ攻撃
攻撃者が過去に傍受した正当な認証応答(Assertion)を再利用して認証を試みる攻撃です。
攻撃者が過去の認証セッションを傍受: ユーザーが正規RPで認証する際に、攻撃者が認証応答(アサーション)を傍受します。
攻撃者が傍受したアサーションを正規RPへ送信: 攻撃者は傍受したアサーションを再度RPサーバーへ送信し、認証を試みます。
RPサーバーがチャレンジを適切に検証しない: RPサーバーが各認証リクエストに対してユニークなチャレンジ(Nonce)を生成し、そのチャレンジが応答で適切に署名されているか、一度しか使用されていないかを検証しない場合、リプレイ攻撃が成功します。
3. RPサーバーの侵害
WebAuthnのセキュリティは認証器とプロトコルだけでなく、RPサーバー側の実装にも大きく依存します。
RPサーバーの脆弱性を悪用: SQLインジェクション、XSS、不適切なAPIアクセス制御などにより、攻撃者がRPサーバーへ侵入します。
登録済み公開鍵データベースの窃取: データベースからユーザーの登録済み公開鍵が窃取されると、攻撃者はユーザーの認証器登録情報を改ざんしたり、不正な認証器を登録したりする可能性があります。ただし、公開鍵自体は秘密情報ではないため、これ単独での認証突破は困難です。
アテステーション秘密鍵の窃取: RPサーバーがアテステーション検証に使用する秘密鍵が窃取された場合、攻撃者は任意の不正な認証器のアテステーションを偽造し、システムに登録させることが可能になります。
セッション情報の窃取: RPサーバーから認証後のセッションクッキーやトークンが窃取された場合、攻撃者は直接ユーザーセッションを乗っ取ることが可能です。
攻撃チェーンの可視化
フィッシングを伴う典型的なアカウント乗っ取りの攻撃チェーンを以下に示します。
flowchart LR
A["攻撃者: 偽の認証サイト構築"] --> B{"ユーザー: 誘導され偽サイトへアクセス"};
B -- 認証リクエスト転送 --> C["攻撃者プロキシ: 正規RPへWebAuthn認証要求"];
C --> D["正規RP: WebAuthnチャレンジ発行"];
D -- チャレンジ転送 --> C;
C -- ユーザーへチャレンジ転送 --> B;
B -- ユーザー: 認証器で署名 --> E["ユーザー: 署名済アサーションを偽サイトへ送信"];
E -- アサーション転送 --> C;
C --> D;
D -- アサーション検証とセッション発行 --> C;
C -- セッション利用 --> F["攻撃者: ユーザーアカウントを乗っ取り"];
style A fill:#f9f,stroke:#333,stroke-width:2px
style F fill:#f9f,stroke:#333,stroke-width:2px
検出と緩和策
FIDO2/WebAuthnの強力なセキュリティは、正しい実装と運用があってこそ発揮されます。以下に主要な検出・緩和策を示します。
1. フィッシング耐性強化
WebAuthnは設計上、認証時にオリジン情報を確認することで強力なフィッシング耐性を提供します。
RP IDの厳格な検証: RPサーバーは、認証応答に含まれるrpIdHashが、自身の登録されたRP IDのハッシュと一致するかを厳格に検証する必要があります。WebAuthn仕様 [2] に基づき、この検証が不正なオリジンからの認証を拒否する要です。
Attestation Conveyance Preferenceの活用: 登録時にattestationプロパティ(none, indirect, direct, enterprise) を設定し、信頼できる認証器からの登録を強制することで、悪意ある認証器の登録を防ぎます。特にdirectやenterpriseは認証器の信頼チェーンの検証を可能にします [2]。
ユーザーへの教育: ユーザーがブラウザのアドレスバーを確認する習慣をつけ、不審なサイトでの認証を避けるよう教育することが重要です。
2. MITM耐性とリプレイ耐性
これらの攻撃は、プロトコルの基盤となる暗号技術とチャレンジ・レスポンス機構によって緩和されます。
TLS (Transport Layer Security) の強制: RPサーバーへのすべての通信はHTTPS/TLSで保護されるべきです。これにより、通信の盗聴や改ざんを防ぎます。HSTS (HTTP Strict Transport Security) を使用して、常にHTTPS接続を強制してください。
動的なチャレンジの生成: 各認証リクエストに対して、暗号学的に安全でユニークなチャレンジ(Nonce)を生成し、そのチャレンジが認証応答に含まれ、かつ正しく署名されていることを検証します [2]。一度使用したチャレンジは無効化し、リプレイ攻撃を防ぎます。
認証カウンターの検証: 多くの認証器は、認証ごとの署名カウンターを含みます。RPサーバーはこのカウンター値を保存し、認証ごとに増加していることを確認することで、認証器のクローンやリプレイ攻撃の兆候を検出できます [2]。
コード例: セキュアなチャレンジ生成(Python)
誤用例: 固定チャレンジ
# Bad: Fixed challenge value. Vulnerable to replay attacks.
# This challenge can be reused by an attacker.
FIXED_CHALLENGE = b"deadbeefdeadbeefdeadbeefdeadbeef" # 絶対にこれを行わない!
# challenge_base64url = base64.urlsafe_b64encode(FIXED_CHALLENGE).rstrip(b'=').decode('ascii')
# verify_authentication_response(response, challenge_base64url, ...)
# 計算量: O(1)
# メモリ: O(1)
安全な代替: 動的なチャレンジ生成
import os
import base64
from typing import Optional
def generate_secure_challenge(length: int = 32) -> str:
"""
暗号学的に安全なランダムなチャレンジ(Nonce)を生成し、Base64URLエンコードして返します。
WebAuthnの認証応答(Assertion)検証に利用されます。
:param length: 生成するチャレンジのバイト数。WebAuthnのベストプラクティスでは、
少なくとも16バイト(128ビット)以上が推奨されます。
:return: Base64URLエンコードされたチャレンジ文字列。
前提: 適切なOSの乱数源が利用可能であること。
計算量: os.urandomはOSの乱数源に依存し、通常O(length)。Base64エンコードもO(length)。
メモリ: O(length)
"""
if length < 16:
raise ValueError("Challenge length must be at least 16 bytes for security.")
challenge_bytes = os.urandom(length)
# WebAuthn仕様ではBase64URLエンコードが推奨される
return base64.urlsafe_b64encode(challenge_bytes).rstrip(b'=').decode('ascii')
# 使用例:
# 認証オプション生成時や認証応答検証時に、常に新しいチャレンジを生成する
# authentication_options = generate_authentication_options(
# rp_id="example.com",
# challenge=generate_secure_challenge()
# )
# ... ユーザーからの応答 ...
# verify_authentication_response(response, authentication_options.challenge, ...)
3. RPサーバーのセキュリティ強化
RPサーバーはFIDO2/WebAuthnにおける信頼の基点であり、そのセキュリティは極めて重要です。
登録情報の暗号化と保護: ユーザーの登録済み公開鍵情報(credential ID, public key, sign counterなど)は、データベースに保存する際に暗号化し、厳重にアクセス制御された環境で管理すべきです。不正な改ざんや窃取を防ぐため、データベースレベルでの暗号化やHSM (Hardware Security Module) の利用を検討します。
Attestation秘密鍵の保護: RPがFIDO MDS [1] を利用せずに自身でAttestation検証を行う場合、Attestation証明書を署名するための秘密鍵が必要となることがあります。これらの秘密鍵はHSMやTPM (Trusted Platform Module) に格納し、厳格なアクセス制御とローテーションポリシーを適用します [3]。
最小権限の原則: RPサーバーの各コンポーネントやデータベースへのアクセスは、最小限の権限に制限します。特に認証情報に関わるデータへのアクセスは、監査ログを伴う厳格な承認プロセスが必要です。
運用対策
FIDO2/WebAuthn認証の導入後も、継続的な運用対策を通じてセキュリティ体制を維持・強化する必要があります。
1. 鍵/秘匿情報の取り扱い
RPサーバーでの登録済み公開鍵の保護: ユーザーが登録した公開鍵は、RPサーバーが管理する最も重要な情報の一つです。これは暗号化されたデータベースに保存し、バックアップも同様に保護されていることを確認します。データの完全性を保証するため、変更不可ログや整合性チェックを導入します。
Attestationルート証明書チェーンの管理: 認証器の信頼性を検証するために使用されるAttestationルート証明書チェーンは、信頼できるソース (FIDO Alliance Metadata Service [1]) から取得し、定期的に更新します。チェーンの改ざんがないことを常に確認してください。
HSM/TPMの活用: RPサーバーがAttestationを生成する側である場合(自身のルート証明書を持つカスタムFIDO認証器を用いる場合など)、Attestation秘密鍵はHSMやTPMといったハードウェアセキュリティモジュールに格納することを強く推奨します。これにより、鍵の物理的な保護と改ざん防止を実現します [3]。
2. ローテーションとライフサイクル管理
Attestation秘密鍵のローテーション: Attestationに使用する秘密鍵は、定期的にローテーションすべきです。例えば、年次またはインシデント発生時に鍵を更新し、古い鍵は安全に失効させます。
ユーザーの認証器登録解除と再登録: ユーザーが認証器を紛失した場合や、デバイスを破棄する際には、速やかにRPサーバーからその認証器の登録情報を解除する手順を確立します。また、疑わしい活動が検出された場合には、ユーザーに全ての認証器を解除させ、再登録を促すなどの対応ポリシーを定めます。
3. 最小権限とアクセス制御
RPサーバーの認証器サービス連携API: RPサーバーがFIDO2認証器と連携するAPI(例えば、WebAuthn API)に対するアクセスは、必要最小限のネットワークセグメントとIPアドレスに制限します。
管理者のアクセス権限: FIDO2設定や認証器登録情報を管理する管理者アカウントには、多要素認証(WebAuthn自体を含む)を義務付け、最小権限の原則を徹底します。監査ログと組み合わせることで、不正なアクセス試行を検出できます。
4. 監査とモニタリング
認証ログの収集と分析: すべての認証試行(成功・失敗)、登録、解除イベントを詳細なログとして収集します。ログには、試行日時、ユーザーID、RP ID、IPアドレス、ユーザーエージェント、結果、認証器タイプなどの情報を含めます。
異常検知: 収集したログをリアルタイムで分析し、異常な認証パターン(地理的変化、短時間での複数回失敗、新しい認証器の不審な登録など)を検出するシステムを導入します。SIEM (Security Information and Event Management) ソリューションとの統合を検討します [3]。
認証器のFIDO MDSチェック: 認証器のメタデータと状態をFIDO MDS [1] と照合し、既知の脆弱性を持つ認証器や、製造元によって失効された認証器の使用を検出・ブロックします。
現場の落とし穴とトレードオフ
誤検知とユーザー体験: 強固なセキュリティポリシー(例: 特定の認証器タイプのみ許可、厳格な生体認証要件)は、正規ユーザーの認証失敗(誤検知)を招き、ユーザー体験を損なう可能性があります。セキュリティレベルと利便性のバランスを考慮したポリシー設計が必要です。例えば、短期間でのPIN入力失敗回数上限を設定する際に、高すぎると総当たり攻撃リスク、低すぎると正規ユーザーがロックアウトされるリスクがあります [3]。
検出遅延とリアルタイム性: 異常検知システムの遅延は、攻撃者がアカウント乗っ取りを完了させる時間を与えてしまいます。リアルタイムに近いログ収集と分析、即時アラート通知の仕組みが不可欠です。例えば、同一ユーザーからの異なる地理的IPからの連続認証失敗をすぐに検知し、対応できる体制を構築します。
可用性と冗長性: FIDO2サービスを提供するRPサーバーは、高可用性を持つ必要があります。単一障害点とならないよう、ロードバランシング、データベースのレプリケーション、地理的冗長性などを考慮し、サービス停止が認証不可につながるリスクを低減します。認証器自体が物理的に破損・紛失するリスクも考慮し、複数の認証器登録やリカバリーオプションを提供することが望ましいです [3]。
まとめ
FIDO2/WebAuthnは、パスワード認証が抱える多くの課題を解決する強力な認証技術であり、フィッシング耐性やユーザー体験の向上に大きく貢献します。しかし、その恩恵を最大限に享受するためには、WebAuthnプロトコルの深い理解に基づいたセキュアな実装と、継続的な運用対策が不可欠です。
本記事で解説した脅威モデル、攻撃シナリオ、そして詳細な検出・緩和策、運用対策は、実務家のセキュリティエンジニアがFIDO2/WebAuthn環境を設計・構築・運用する上での重要な指針となるでしょう。特に、チャレンジの動的な生成、TLSの強制、RPサーバーでの鍵保護、そして監査・モニタリングは、セキュリティの堅牢性を確保するための要となります。常に最新のセキュリティ情報にアンテナを張り、変化する脅威に対応できるよう、継続的な改善サイクルを回していくことが求められます。
参考文献:
FIDO Alliance. “The FIDO2 Project”. (最終アクセス日: 2024年7月30日). URL: https://fidoalliance.org/fido2/
W3C. “Web Authentication: An API for accessing Strong Authentication Credentials – Level 3”. Candidate Recommendation, 2024年7月1日. URL: https://www.w3.org/TR/webauthn-3/
NIST. “Special Publication 800-63B: Digital Identity Guidelines: Authentication and Lifecycle Management”. November 2023. URL: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-63b.pdf
コメント