令和3年度 春期 情報処理安全確保支援士試験 午後Ⅰ 問1|「ソーシャルログイン」に潜む罠——情報処理安全確保支援士で学ぶOAuth認可コードフローのセキュリティ
この記事で扱うセキュリティ事例
- 試験区分: 情報処理安全確保支援士
- 出典: 令和3年度 春期 情報処理安全確保支援士試験 午後Ⅰ 問1
- 主なテーマ: OAuth 2.0(Authorization Code Grant)、ソーシャルログイン、認可と認証の違い、認可コード横取り(ログインCSRF)、stateパラメータ、最小権限、可用性
この記事は「情報処理安全確保支援士 午後問題 全70問」シリーズの1本です。→ 全70問の一覧・テーマ別索引はこちら
導入: なぜこの事例が重要なのか
「Googleでログイン」「LINEでログイン」——いまや多くのWebサービスが、こうしたソーシャルログインのボタンを備えています。利用者はサービスごとにパスワードを覚える必要がなく、サービス提供側も認証の手間を外部に任せられる。便利で合理的な仕組みです。その裏側を支えているのが、OAuthというプロトコルです。
情報処理安全確保支援士試験の午後Ⅰで出題されたこの事例は、ファイル共有サービスを運営するベンチャー企業が、多要素認証の導入を狙ってソーシャルログイン(OAuthのAuthorization Code Grant)を実装していく物語です。ところが、実装の最終段階でセキュリティレビューを受けると、三つの問題が次々と指摘されます。なかでも怖いのが、利用者が罠サイトに誘導されると、知らないうちに「攻撃者のアカウント」にログインさせられ、自分のファイルが攻撃者の手元にダウンロードされてしまうという攻撃でした。
この記事を読むと、OAuthが扱っているのは「認証」ではなく「認可」だという根本、認可コードを横取りする攻撃の仕組み、それを防ぐstateパラメータの役割、そして「最小権限」「可用性」という設計上の勘所が見えてきます。OAuthは現役で広く使われている技術だけに、受験者にも実務者にも、知っておいて損のないテーマです。
インシデントの概要
舞台は、従業員10名のベンチャー企業S社です。S社のファイル共有サービス(Sサービス)は機能が豊富で、登録会員(S会員)の数を伸ばしていました。S会員は、認証された状態で写真などのファイルを自分のフォルダにアップロードでき、そのファイルにアクセスするためのURLをメールなどで他人に伝えれば、ファイルを共有できます。サービス内でメッセージや「いいね」も送れました。
Sサービスの企画・開発・運用は、CTOのF氏が取り仕切っていました。前回の脆弱性診断で、利用者IDとパスワードで認証するSサービスの認証モジュール(S認証モジュール)について、「認証方式を多要素認証にする方がよい」とのアドバイスを受けていたものの、その実装が課題として残っていたのです。
そこでF氏は一計を案じます。多要素認証などの機能をもつT社のサービス(Tサービス。認証認可を提供するSNS)とSサービスをID連携させれば、S認証モジュールを自前で多要素化しなくても、Tサービスの多要素認証を借りられる——。この改修では、OAuthのAuthorization Code Grant(認可コードを介してアクセストークンを得る方式)を採用することにしました。S社は、ID連携技術に詳しい情報処理安全確保支援士(登録セキスペ)のY氏を外部から招聘し、実装の最終段階でレビューを受けることを前提に、改修を承認しました。
技術的には筋のよい判断に見えました。しかし、OAuthは「正しく使えば安全」だが「使い方を一つ誤ると穴が空く」プロトコルでもあります。Y氏のレビューは、その「一つの誤り」を見逃しませんでした。
何が起きたのか

まず、OAuthの登場人物を整理しておきましょう。この事例では三つの主体がいます。Tサービスのアカウントをもち、S会員登録を希望する「利用者」。利用者のTサービスでのアカウント名を要求する「Sサービス」。そして、認可認証を提供するSNSであり、各種の権限を提供する「Tサービス」です。
ここで肝心なのは、Sサービス(OAuthでいうクライアント)は、利用者が許可した範囲でTサービスが提供するリソースにアクセスできる、という構図です。なぜアクセスできるのか——それは利用者が、自分のアカウント情報などを取得する権限を、Sサービスに与えるからです。利用者は、Sサービスに与える権限を、シーケンスの「認証、権限付与の確認」の通信の際に確認します。どの権限を要求するかを決めるのはSサービスの実装者です。S社では、要求した権限のいずれか一つでも利用者が拒否すれば、シーケンスを止める実装にしました。OAuthは本来「認可(誰に何を許すか)」の仕組みであり、それをログイン(認証)に転用しているのがソーシャルログインだ——この理解が、後の問題を読み解く鍵になります。
さて、Y氏のレビューです。Y氏はセキュリティ上の問題を三つ指摘しました。
一つ目の問題は、最も巧妙でした。Y氏は、次の攻撃シナリオで説明します。Sサービスにログインしていない利用者が、攻撃者の用意した罠サイトにアクセスすると、ある攻撃シーケンスが走る。そして後に、利用者が攻撃を受けているとは知らずにSサービスにファイルをアップロードすると、そのファイルが攻撃者にダウンロードされてしまうおそれがある——。
仕組みはこうです。攻撃者はまず、自分自身のTサービスアカウントを使ってOAuthの認可フローを途中まで進め、「攻撃者のアカウントに対応する認可コード」を手に入れます。認可コードとは、認証・権限付与の確認が済んだ証として、後でアクセストークンと引き換えるための一時的な引換券のようなものです。攻撃者は、この自分用の認可コードを罠サイトに仕込んでおきます。何も知らない利用者が罠サイトにアクセスすると、利用者のブラウザが、攻撃者の認可コードを付けてSサービスへリダイレクト(自動的に別のURLへ転送)させられる。Sサービスはその認可コードを受け取り、アクセストークンを要求して取得し、「攻撃者のアカウントでログインした状態」を利用者のブラウザに作ってしまうのです。
利用者は、自分のアカウントにログインしているつもりで、実は攻撃者のアカウントにログインしている。だからファイルをアップロードすれば、それは攻撃者のフォルダに保存される。攻撃者は自分のアカウントなので、そのファイルを悠々とダウンロードできる——これが、ファイルが攻撃者に渡る仕掛けでした。一般に「ログインCSRF」や「認可コード横取り」と呼ばれる類型です。
この攻撃への対策として、RFC 6749(OAuth 2.0の仕様)は、推測困難な値であるstateパラメータの利用を推奨しています。Sサービスはstateパラメータを、認可の要求を送信する際に付与する。そして認可コードを受信する際に、そのセッションがstateパラメータを付与したときのセッションと同一かどうかを確認し、同一である場合だけシーケンスを続ける。こうすれば、攻撃者が仕込んだ「別セッションの認可コード」は、stateの不一致ではじかれます。利用者のブラウザのセッションと、認可フローを開始したセッションが結びついているかを確かめる——これがstateの本質的な役割です。
二つ目の問題は、SサービスがTサービスに要求する権限が、必要最小限になっていないことでした。S社は「将来どの権限も使うかもしれない」と考えて、提供される全権限を要求する実装にしていたのです。しかし、ログインに本当に必要なのは利用者を識別するための情報だけ。過剰な権限を要求すれば、万一トークンが漏れたときの被害も、利用者の不安も大きくなります。この問題は、要求する権限を一つだけにすることで解決しました。
三つ目の問題は、Tサービスに深刻な脆弱性が報告された場合の対応方法を決めていなかったことです。外部サービスに依存する以上、その外部が危なくなったときにどうするかを、あらかじめ決めておく必要があります。この問題には、Tサービスとの連携を一時的に停止し、S認証モジュールだけで認証する、という方針で対処することにしました。ただしこのとき、一部のS会員——具体的には、S認証モジュールに利用者IDとパスワードを登録していないS会員——はSサービスを利用できなくなります。新規にID連携だけで登録した会員は、そもそもSサービス側にパスワードを持っていないからです。そこで、その会員向けに代替策を検討することになりました。
最後に、利用者認証の実現方法も確認されました。Sサービスは利用者を直接認証していないのに、どうやってS会員を認証しているのか。Y氏の解説によれば、Sサービスは、Tサービスで認証されたS会員のT-ID(Tサービスのアカウント名。変更できない)が、Sサービス内に登録されていることを確認することで、利用者認証を実現していたのです。「Tサービスが本人だと認めた人物のIDが、自社の会員台帳に載っているか」を照合する——これがソーシャルログインによる認証の実体でした。
S社は、Y氏から指摘された三つの問題をすべて解決したうえで、TサービスとSサービスのID連携を開始しました。
ここから先は

情報処理安全確保支援士(登録セキスペ)の午後問題、「読んでも頭に入らない」と感じていませんか?本シリーズでは、2017年〜2025年の過去…
この記事が気に入ったらチップで応援してみませんか?
