課題とコンテキスト
あるHTTPSページが、ユーザーによるUSBデバイスの設定を支援します。ユーザーが「デバイスを接続」をクリックした後、ブラウザは明示的な権限プロンプトを表示する必要があります。ページは、非対応ブラウザ、埋め込みiframe、切断、権限拒否、およびリロード後の復旧を適切に処理しなければなりません。
機能検出、ユーザー操作、オリジンとPermissions Policy、デバイスフィルター、データ最小化、エラー処理、プログレッシブエンハンスメント、テストについて説明してください。ページはロード時に密かにスキャンしたり、生のデバイスデータをサードパーティの分析ツールに送信したりしてはなりません。
面接官がテストするポイント
面接官は、WebUSBを通常のDOMデバイスリストではなく、権限によって制御される強力なWeb APIとして扱えるかどうかを見ています。MDNはデバイス要求時のブラウザプロンプトについて説明しており、Permissions APIの結果はセキュアコンテキスト、Permissions Policy、ユーザー操作、およびプロンプトの状態に影響を受けます。
優れた回答は、権限を付与するオリジン、トップレベルページ、埋め込みポリシー、デバイスフィルター、接続ライフサイクルを結びつけて説明します。ChromeはPermissions Policyを明示的に設定することを推奨しており、最終的な許可判断はユーザーに委ねられます。プログレッシブエンハンスメントにより、WebUSB非対応のユーザーに対しても分かりやすい説明、ネイティブツールのリンク、またはサポート窓口を提供します。
30秒の回答
「まずHTTPSとnavigator.usbを検出し、非対応の場合はドキュメントやネイティブツールを案内します。ユーザーの『接続』ボタンからのみrequestDevice()を呼び出し、正確なベンダーおよびプロダクトフィルターを使用します。信頼できるオリジンのみを許可するレスポンスPermissions Policyを設定し、埋め込みフレームも検証します。接続後はタスクに必要なインターフェースのみにアクセスし、レスポンスを検証し、切断イベントをリッスンします。拒否、ポリシーによるブロック、一致なし、非対応ブラウザをサーバーエラーとしてではなく、それぞれ区別された対処可能な状態として扱います。」
ステップごとの設計
ステップ1: 信頼境界と目標の確立
ページが実際に必要とするコマンドとデータ、デバイスに機密情報が含まれているかどうか、そしてWebUSBが必須かどうかを定義します。より特化したブラウザAPIやネイティブツールが存在する場合は、それを優先します。利便性のためだけにすべてのインターフェースを読み取ってはなりません。
ステップ2: 機能検出とプログレッシブエンハンスメント
HTTPS、ブラウザの機能、および必要なメソッドを確認します。サポートされていない場合は、ドキュメント、ドライバーやネイティブアプリの案内、問い合わせサポートを提供します。機能検出によってエンハンスメントの分岐を選択しますが、APIが存在することが権限の付与やデバイスの互換性を意味するわけではありません。
ステップ3: 権限をユーザー操作にバインドする
明確なクリックまたはキーボード操作からrequestDevice()を呼び出し、ブラウザの権限プロンプトが表示されることをユーザーに説明します。ロード中、タイマー、非表示のiframe、または無関係な非同期コールバック内でリクエストしてはなりません。キャンセル、ポリシーによるブロック、非対応ブラウザ、一致するデバイスがない場合を区別し、有用な次のステップを提示します。
ステップ4: オリジンとPermissions Policyの制限
Permissions-Policy: usb=(self)や、より限定された信頼済みオリジンリストなどの明示的なヘッダーを設定します。埋め込みの場合は、トップレベルオリジン、iframeのallow属性、およびポリシーを総合的に検証し、すべてのサードパーティに許可を与えないようにします。CSP、Trusted Types、依存関係のレビューにより、ページ自体を引き続き保護します。
ステップ5: デバイスのフィルタリングとアクセスの最小化
無関係なデバイスが表示されないように、ベンダー、プロダクト、またはプロトコルでフィルタリングします。接続後は、必要な構成とインターフェースのみを列挙し、読み書きのタイムアウトとメッセージサイズ制限を強制し、レスポンス形式を検証します。タスク完了後にインターフェースを解放し、シリアル番号、生のパケット、個人特定データを分析ツールから除外します。
ステップ6: 接続、切断、リロードの処理
connectとdisconnectをリッスンし、デバイス名、現在のステップ、再接続アクションを表示します。切断時はポーリングを停止し、ハンドルをクリアします。再接続時にはフィルタリングとタスク確認を再度実行します。リロード後は、以前の接続や権限がそのまま使用可能であると見なさず、ユーザーに再度選択させます。
ステップ7: エラーおよびプライバシーUXの設計
「権限がキャンセルされました」という表示をサーバー障害のように見せてはなりません。ポリシーブロックの場合は管理者または埋め込み元の所有者を案内し、一致するデバイスがない場合は対象モデルの接続方法を説明します。生のデバイスデータではなく、安定したカテゴリと相関IDをログに記録します。サードパーティにマスキング済み診断データを送信する前に、別途同意を取得します。
ステップ8: 環境とセキュリティリグレッションの検証
非セキュアコンテキスト、複数ブラウザ、iframe、ポリシーブロック、拒否、一致なし、ダブルクリック、切断、スリープと復帰、悪意のあるデバイスレスポンスをテストします。すべてのプロンプトがユーザー操作に従っていること、ポリシーが想定されたオリジンのみを許可していること、フォールバックによってヘルプパスが正常に完結することを確認します。
トレードオフ、境界、情報利得
厳格なフィルターは誤選択やプライバシーの漏洩を減らしますが、古いファームウェアを除外する可能性があります。バージョン管理された互換性ルールにより、そのトレードオフを明示化できます。自動再接続はUXを向上させますが、ユーザーの新たな選択をバイパスしたり、古いハンドルを信頼済み状態として扱ったりしてはなりません。
Permissions Policyは埋め込みオリジンを制限しますが、デバイスへのアクセス許可そのものではありません。ブラウザは依然としてユーザーに確認を求めます。プログレッシブエンハンスメントには設計とテストのコストがかかりますが、機能差を白紙の画面ではなく、明確な次のステップへと転換できます。
模範的な質の高い回答
「WebUSBは、オリジンとユーザー権限によって制約されるエンハンスメントとして扱います。HTTPS環境でAPIを検出し、非対応の場合はネイティブツールを提供します。正確なフィルターを指定したrequestDevice()の呼び出しは、接続ボタンからのみ行います。レスポンスヘッダーにより信頼できるオリジンにUSBを許可し、埋め込みフレームはトップレベルポリシーとallow属性を満たす必要があります。
接続後は、必要なインターフェースのみにアクセスし、レスポンスを検証し、時間とメッセージサイズを制限し、生のパケットは決してログに記録しません。切断をリッスンしてハンドルを破棄し、ユーザーに再接続を求めます。リロード後は再度選択を促します。キャンセル、ポリシーブロック、一致なし、非対応ブラウザのそれぞれに特定の次のアクションを用意します。テストではブラウザ、iframe、切断、悪意のあるレスポンス、フォールバックUXを網羅します。」
よくある間違い
- ページロード時に
requestDevice()を呼び出す。 権限リクエストは明示的なユーザー操作に従う必要があります。 - WebUSBを通常のデバイス列挙のように扱う。 セキュアコンテキスト、ポリシー、ブラウザの権限のすべてが重要です。
- 空または広すぎるフィルターを使用する。 ユーザーが無関係なデバイスを選択し、不要なデータを公開してしまうリスクがあります。
- すべてのiframeにUSBアクセスを許可する。 サードパーティオリジンにデバイスへのより大きな攻撃対象領域を与えてしまいます。
- 古いハンドルを自動的に復元する。 リロード、切断、および権限の状態が変わっている可能性があります。
- 生のデバイスパケットをログに記録する。 診断ログに機密データやシリアル番号が含まれる可能性があります。
- 単一のブラウザしかサポートしない。 WebUSB非対応のユーザーにも機能するフォールバックが必要です。
- 拒否をサーバーエラーとして表示する。 ユーザーには再試行または管理者によるアクションが必要です。
フォローアップの質問と回答
なぜ権限リクエストはユーザー操作に従わなければならないのですか?
デバイスへのアクセスはプライバシーとセキュリティに影響するためです。ブラウザは、どのオリジンがどのデバイスを要求しているかをユーザーが認識している必要があり、ユーザー操作によってプロンプトが表示されるタイミングを制約します。
Permissions Policyはブラウザプロンプトとどのように関連していますか?
ポリシーは、ドキュメントがその機能を使用する資格があるかどうかを決定します。許可されている場合でも、ブラウザはプロンプトを表示する前にオリジン、コンテキスト、ユーザーの選択を適用します。両方のレイヤーを通過する必要があります。
切断後の再接続はどのように処理しますか?
I/Oとポーリングを停止し、ハンドルをクリアし、再接続をリッスンして、一致するデバイスをユーザーに確認させます。バックグラウンドで無限にリトライしてはなりません。
なぜ診断のためにすべてのインターフェースを読み取らないのですか?
アクセスを最小限に抑えることで、プライバシー侵害、プロトコル誤操作、およびドライバー互換性のリスクが低減されます。診断には、明確なユーザー操作、最小限のフィールド、および個別のログ送信同意が必要です。
WebUSB非対応の場合はどうしますか?
ドキュメント、ドライバーまたはネイティブツール、互換性ガイド、および問い合わせサポートを提供します。中核となる目標を単に『他のブラウザを使ってください』で済ませてはなりません。