メインコンテンツまでスキップ

FIDO2/WebAuthn 実装改善バックログ

概要

FIDO2/WebAuthn実装の現状分析と残課題をまとめたドキュメント。 現在の実装は基本機能が完成しており、本番運用可能な状態だが、いくつかの改善点が存在する。

現在の実装状況

完成済み機能

機能状態備考
登録チャレンジ生成WebAuthn4jRegistrationChallengeExecutor
登録検証・保存WebAuthn4jRegistrationExecutor
認証チャレンジ生成WebAuthn4jAuthenticationChallengeExecutor
認証検証WebAuthn4jAuthenticationExecutor
マルチクレデンシャル対応1ユーザーで複数パスキー登録可能
マルチテナント対応全クエリで tenant_id 使用
PostgreSQL対応PostgresqlExecutor
MySQL対応MysqlExecutor
signCount検証(クローン検出)認証時にカウンタ検証
transports保存UX最適化用
credProtect保存保護レベル
Resident Key (Discoverable Credential)rk フラグ保存

アーキテクチャ

┌─────────────────────────────────────────────────────────────────┐
│ Application Plane API │
├─────────────────────────────────────────────────────────────────┤
│ Fido2RegistrationChallengeInteractor │
│ Fido2RegistrationInteractor │
│ Fido2AuthenticationChallengeInteractor │
│ Fido2AuthenticationInteractor │
├─────────────────────────────────────────────────────────────────┤
│ WebAuthn4j Adapter │
├─────────────────────────────────────────────────────────────────┤
│ WebAuthn4jRegistrationChallengeExecutor │
│ WebAuthn4jRegistrationExecutor │
│ WebAuthn4jAuthenticationChallengeExecutor │
│ WebAuthn4jAuthenticationExecutor │
├─────────────────────────────────────────────────────────────────┤
│ WebAuthn4jCredentialRepository (Interface) │
│ └── WebAuthn4jCredentialDataSource (Implementation) │
│ ├── PostgresqlExecutor │
│ └── MysqlExecutor │
└─────────────────────────────────────────────────────────────────┘

残課題一覧

Phase 1: 高優先度

1.1 エラーハンドリング改善 ✅

課題: クレデンシャル検索失敗時のエラーハンドリングが不適切

現状:

  • WebAuthn4jCredentialDataSource.get()NotFoundException をスロー
  • WebAuthn4jAuthenticationExecutor で generic Exception としてキャッチ
  • 結果: 500 Internal Server Error として返却

対象ファイル:

  • libs/idp-server-webauthn4j-adapter/src/main/java/org/idp/server/authenticators/webauthn4j/WebAuthn4jAuthenticationExecutor.java:87
  • libs/idp-server-webauthn4j-adapter/src/main/java/org/idp/server/authenticators/webauthn4j/datasource/credential/WebAuthn4jCredentialDataSource.java:75

改善案:

// WebAuthn4jAuthenticationExecutor.java
try {
WebAuthn4jCredential credential = credentialRepository.get(tenant, id);
// ...
} catch (NotFoundException e) {
log.warn("Credential not found: id={}, tenant={}", id, tenant.identifier());
return AuthenticationResult.clientError("credential_not_found", "Credential not found for this user");
} catch (WebAuthn4jBadRequestException e) {
// existing handling
}

期待される動作:

  • 404 Not Found レスポンス
  • 明確なエラーメッセージ: credential_not_found
  • ログ出力(警告レベル)

1.2 allowCredentials検証の追加(CVE-2025-26788対策) ✅

課題: Non-Discoverable Credential認証時にallowCredentialsリストの検証がスキップされている

背景:

idp-serverの現状:

  • 脆弱ではない: ユーザー識別がCredential IDから逆引きされるため、攻撃者は自分自身としてしか認証できない
  • ただし: allowCredentials検証をスキップしており、Defense in Depthの観点で改善が必要

現状コード:

// WebAuthn4jAuthenticationManager.java:86
List<byte[]> allowCredentials = null; // 常にnull

対象ファイル:

  • libs/idp-server-webauthn4j-adapter/src/main/java/org/idp/server/authenticators/webauthn4j/WebAuthn4jAuthenticationManager.java:86
  • libs/idp-server-webauthn4j-adapter/src/main/java/org/idp/server/authenticators/webauthn4j/WebAuthn4jChallenge.java

改善案:

// WebAuthn4jChallenge.java
public class WebAuthn4jChallenge implements Challenge {
// 既存フィールド
private List<byte[]> allowCredentials; // 追加

public List<byte[]> getAllowCredentials() {
return allowCredentials;
}
}

// WebAuthn4jAuthenticationManager.java
private AuthenticationParameters toAuthenticationParameters(
CredentialRecordImpl credentialRecord) {
// ...
List<byte[]> allowCredentials = challenge.getAllowCredentials(); // nullではなくチャレンジから取得
// ...
}

期待される動作:

  • Non-Discoverable Credentialフローで、許可されていないCredential IDを拒否
  • Discoverable Credentialフローでは引き続きnull(仕様通り)
  • エラー時: credential_not_allowed エラーを返却

優先度: 高(セキュリティ強化)


1.4 クレデンシャル一覧API

課題: 登録済みパスキーの一覧取得APIが未実装

バックエンド実装: ✅ 完了

  • WebAuthn4jCredentialRepository.findAll(Tenant, String userId)
  • WebAuthn4jCredentialRepository.findByUsername(Tenant, String username)

必要な作業:

  1. Control Plane API エンドポイント追加
    • GET /v1/users/{userId}/credentials
    • GET /v1/credentials?username={username}
  2. OpenAPI定義追加
  3. レスポンス形式定義

レスポンス例:

{
"credentials": [
{
"id": "abc123...",
"created_at": "2024-01-15T10:30:00Z",
"last_used_at": "2024-01-20T08:00:00Z",
"device_name": "iPhone 15 Pro",
"transports": ["internal"],
"backup_eligible": true,
"backup_state": true
}
]
}

1.5 クレデンシャル削除API

課題: パスキー削除APIが未実装

バックエンド実装: ✅ 完了

  • WebAuthn4jCredentialRepository.delete(Tenant, String credentialId)

必要な作業:

  1. Control Plane API エンドポイント追加
    • DELETE /v1/credentials/{credentialId}
  2. 削除前の検証ロジック
    • 最後の1つを削除する場合の警告/拒否
  3. セキュリティイベントログ出力

Phase 2: 中優先度

2.1 デバイス名フィールド追加

課題: パスキーに人間が読める名前を付けられない

必要な作業:

  1. DBスキーマ変更
    ALTER TABLE webauthn_credentials ADD COLUMN device_name VARCHAR(128);
  2. Flyway マイグレーション追加
  3. WebAuthn4jCredential モデル更新
  4. 登録時のデバイス名自動検出(User-Agent解析)

2.2 クレデンシャル名変更API

課題: 登録後にパスキーの表示名を変更できない

必要な作業:

  1. Control Plane API エンドポイント追加
    • PUT /v1/credentials/{credentialId}
    • Request body: { "device_name": "My MacBook" }
  2. Repository メソッド追加
    • updateDeviceName(Tenant, String credentialId, String deviceName)

2.3 パスキー管理UI(sample-web)

課題: ユーザーがパスキーを管理するUIがない

必要な作業:

  1. パスキー一覧コンポーネント
  2. 削除確認ダイアログ
  3. 名前変更機能
  4. 最終使用日時表示

Phase 3: 低優先度

3.1 WebAuthn Level 3 Backup Flags対応 ✅

課題: バックアップ関連フラグが保存されていない

対応内容:

  • Core + JSONB パターンでDDL再設計
  • backup_eligible (BE)、backup_state (BS) をCore Columnとして追加
  • 登録時にAuthenticator Dataからフラグを抽出
  • WebAuthn4jCredentialConverter でフラグを使用

3.2 セキュリティイベントログ連携 ✅

課題: FIDO2関連イベントがセキュリティイベントログに出力されていない

対応内容: 全Interactorで DefaultSecurityEventType を使用済み

Interactorイベント
Fido2RegistrationChallengeInteractorfido2_registration_challenge_success/failure
Fido2RegistrationInteractorfido2_registration_success/failure
Fido2AuthenticationChallengeInteractorfido2_authentication_challenge_success/failure
Fido2AuthenticationInteractorfido2_authentication_success/failure
Fido2DeregistrationInteractorfido2_deregistration_success/failure

3.3 レート制限

課題: 認証チャレンジ生成のレート制限がない

リスク:

  • DoS攻撃によるリソース枯渇
  • チャレンジ総当たり攻撃(理論上)

対応案:

  • IPベースのレート制限
  • ユーザーベースのレート制限
  • Exponential backoff

3.4 クレデンシャルメタデータ拡張

課題: セキュリティ監査用の情報が不足

追加すべきフィールド:

フィールド用途
registered_ip登録時IPアドレス
registered_user_agent登録時User-Agent
last_used_ip最終使用時IP
last_used_user_agent最終使用時User-Agent

関連ファイル一覧

コア実装

ファイル説明
WebAuthn4jCredential.javaクレデンシャルモデル
WebAuthn4jCredentialRepository.javaリポジトリインターフェース
WebAuthn4jCredentialDataSource.javaリポジトリ実装
WebAuthn4jRegistrationChallengeExecutor.java登録チャレンジ生成
WebAuthn4jRegistrationExecutor.java登録検証
WebAuthn4jAuthenticationChallengeExecutor.java認証チャレンジ生成
WebAuthn4jAuthenticationExecutor.java認証検証
WebAuthn4jConfiguration.java設定クラス

データベース

ファイル説明
V0_9_27_2__webauthn4j.sqlPostgreSQLスキーマ
V0_9_27_2__webauthn.mysql.sqlMySQLスキーマ
PostgresqlExecutor.javaPostgreSQL実装
MysqlExecutor.javaMySQL実装

フロントエンド(app-view)

ファイル説明
src/pages/signup/fido2/index.tsxパスキー登録画面
src/pages/signin/fido2/index.tsxパスキー認証画面
src/pages/add-passkey/index.tsxパスキー追加(メール入力)
src/pages/add-passkey/verify/index.tsxパスキー追加(コード検証)

参考情報

WebAuthn仕様

関連Issue/PR

  • TBD: GitHub Issue作成時にリンク追加

更新履歴

日付内容
2026-01-20初版作成
2026-01-211.2 allowCredentials検証追加(CVE-2025-26788対策)
2026-01-211.1, 1.2 実装完了
2026-01-223.1 WebAuthn Level 3 Backup Flags対応(Core + JSONB DDL再設計)
2026-01-223.2 セキュリティイベントログ連携(実装済み確認)