セキュリティ

OAuth callback URLを含むHTMLを共有するときのリスクと対策

OAuth callback URLが埋め込まれたHTMLを外部に共有すると、不正な認可フローの踏み台を提供したり、アクセストークンが意図しない相手に渡ったりするリスクがある。AIが生成するデモHTMLにはこのパターンが出やすく、動作確認を優先するあまりセキュリティ上の問題が見過ごされがちだ。

なぜ危ないのか

OAuth callback URLとは、認可サーバーが認証完了後にブラウザをリダイレクトするURLだ。このURLがHTMLに書かれており、かつそのHTMLが公開されている場合、攻撃者はredirect_uriを本物に偽装した認可リクエストを送り、被害者のアクセストークンを自分のエンドポイントで受け取るフローを構成できる可能性がある。

特に問題なのは、AIが動くデモを優先するために、callback URLをHTMLにハードコードし、さらにトークン取得のfetchリクエストまでフロントエンドで実装してしまうケースだ。この場合、HTMLを受け取った第三者がブラウザの開発者ツールでネットワークタブを確認するだけで、トークン取得の全プロセスが見えてしまう。

テスト用に作ったHTMLが、何らかの経緯で本番に使われることもある。「デモ用に作ったものをそのまま流用した」というのは事故の典型的なパターンで、テスト用のclient_idと本番用のclient_idを同じHTMLで使い回すことで、意図せずテスト用の設定が本番環境に混入することになる。

  • 相手がログインなしで開ける状態か確認する
  • PCとスマホで最低1回ずつ表示を確認する
  • 内部情報・個人情報・不要な外部送信が残っていないか見る
  • レビュー期限と修正時の差し替え方を決めておく

ソースで見る場所

HTMLのscriptブロックまたは読み込まれるJSファイルで、fetchまたはXMLHttpRequestでトークンエンドポイントにリクエストしている箇所を探す。`grep -n 'token\|grant_type\|authorization_code' output.html`でヒットした行を確認し、`client_secret`が含まれるリクエストボディが組み立てられていないかをチェックする。

OAuthの認可URLを構成しているコードを探す。`response_type=code`や`scope=`といったパラメータを文字列として組み立てている箇所が見つかったら、そこに使われている`client_id`の値を控えておき、OAuth Providerのコンソールで誰のアカウントで登録されたアプリかを確認する。

コールバック処理を担う関数またはeventListenerを探す。URLハッシュやパラメータから`code=`や`access_token=`を取り出す処理がある場合、その後の処理でトークンをlocalStorageや外部APIに送信していないかを確認する。送信先が自社のドメイン以外を含む場合は危険信号だ。

  • HTML内の外部script・form action・iframeを確認する
  • APIキーやトークンらしき文字列がないか検索する
  • 画像・CSS・JSのパスが公開後も解決できるか見る
  • noindexと認証を混同せず、必要なら両方設定する

安全に共有する設定

OAuthフローを含むHTMLを共有する場合は、テスト専用のOAuthアプリをProviderコンソールで作成し、redirect_uriをローカルホストまたはテスト用ドメインのみに限定する。本番用のclient_idは使わず、テスト用アプリのredirect_uriに実際の公開URLを追加しないことで、共有HTMLを使った不正なフローを防ぐ。

どうしても外部向けにOAuth機能を見せる場合は、ギガサイト便のような会社ドメイン認証付き共有URLを発行し、特定の組織のメールアドレスを持つ人だけがアクセスできる設定にする。これにより、不特定多数がHTMLにアクセスして認可フローを試みるリスクを大きく減らせる。

OAuthの動作を見せることが目的の場合、実際のOAuthを使わずにモック認証(固定のテストユーザーで即時ログイン成功にする)として実装したHTMLを共有する方が安全だ。UIの確認はモックで十分なケースが多く、実際のOAuthが必要になるのは本番環境に近い受け入れテストの段階だ。

  • HTML内の外部script・form action・iframeを確認する
  • APIキーやトークンらしき文字列がないか検索する
  • 画像・CSS・JSのパスが公開後も解決できるか見る
  • noindexと認証を混同せず、必要なら両方設定する

再発防止ルール

AI生成のHTMLでOAuth実装が含まれる場合、プロジェクトのコーディング規約に「client_secretはフロントエンドに記述しない」「callback処理はサーバーサイドのエンドポイントで行う」という二つのルールを追加する。これをPRのチェックリストに組み込むと、レビュー時の見落としを防げる。

使い終わったテスト用OAuthアプリは必ずコンソールから削除する手順を定める。共有URLの有効期限が切れた日と同じタイミングでOAuthアプリを削除するカレンダーリマインダーを設定しておくと、削除を忘れたまま放置するケースを防げる。

OAuth関連の事故を防ぐために、四半期に一度OAuthアプリの一覧をProviderコンソールで確認し、現在も必要なアプリと不要なアプリを仕分けるレビューを行う。長期間使われていないアプリは削除し、使用中のアプリはredirect_uriの設定が最小限になっているかを確認する。

  • HTML内の外部script・form action・iframeを確認する
  • APIキーやトークンらしき文字列がないか検索する
  • 画像・CSS・JSのパスが公開後も解決できるか見る
  • noindexと認証を混同せず、必要なら両方設定する

よくある質問

OAuth Providerがredirect_uriを厳密に検証しているなら、callback URLがHTMLに書かれていても問題ないのではないですか?

ProviderのURL検証はフローの整合性を守るが、HTMLに書かれたclient_idとcallback URLの組み合わせを見た攻撃者がフィッシングページを作る材料にすることは防げない。情報を公開しないこと自体が防御の一層になる。

テスト用OAuthアプリを本番と分ける場合、GitHubのシークレットやvercelの環境変数で管理するのが良いですか?

はい。client_idとclient_secretはリポジトリのシークレットや環境変数として管理し、HTMLに直書きしない設計が基本だ。ローカル開発では.envファイルに書きgitignoreに追加し、CI/CDでは環境変数として注入する構成が標準的だ。

共有URLの有効期限が切れた後も、OAuthアプリ自体は削除しなくてよいですか?

共有URLが失効してもOAuthアプリは残り続けるため、攻撃者がclient_idを使って認可リクエストを送ることは引き続き可能だ。使い終わったテスト用アプリはURLの失効と同時に削除することを推奨する。

関連記事

セキュリティ

http混在を含むHTMLを共有するときのリスクと対策

http混在を含むHTMLを共有した場合のリスクを把握し、適切な対処法を選びたい方向け。ブラウザによる表示ブロックや通信傍受のリスクを具体的に示しながら、修正・代替策・共有設定の3つの観点から対策を解説します。

5分で読める
セキュリティ

XSSを含むHTMLを共有するときのリスクと対策

XSSが含まれる可能性のあるHTMLを共有するリスクを把握し、適切な対策を講じたい担当者向け。被害シナリオ、コードレベルの修正方法、CSPによる軽減策、再発防止の仕組みづくりを段階的に解説します。

5分で読める
セキュリティ

オープンリダイレクトを含むHTMLを共有するときのリスクと対策

オープンリダイレクトを含むHTMLを外部共有するリスクを理解し、修正判断と対策を迷わず行いたいチームリーダー・開発者向け。フィッシング被害の具体的なシナリオと、許可リスト実装・URL認証による二段階対策を解説する。

6分で読める
セキュリティ

社外レビュー前にOAuth callback URLを検出するチェックリスト

OAuth callbackを含むAI生成HTMLを社外レビュー前に確認したい開発者・セキュリティ担当向け。client_secretの有無確認からcallback URLの登録設定まで、共有可否を判断するための手順と基準をまとめた実践的なチェックリスト記事。

6分で読める
「セキュリティ」の記事をもっと見る →