【入門編】OAuth 2.0 における認可コード横取り攻撃とPKCEの必須化 – アプリケーションセキュリティ & 安全な開発防御ガイド

「あなたの家の鍵、配達中にすり替えられたら?」OAuth 2.0とPKCEで守るログインの裏側

こんにちは!セキュリティの世界へようこそ。
日々、技術の進化に追いつくのは大変ですよね。今日は、Webアプリ開発の現場で避けては通れない「OAuth 2.0」と、そのセキュリティを劇的に高める「PKCE(ピーシーケーイー)」という技術について、泥棒に例えてお話しします。

「認証」は、いわばあなたの家の玄関の鍵です。でも、もしその鍵を渡すプロセス自体が狙われていたら?そんな恐ろしいシナリオを一緒に見ていきましょう。

—

1. 認可コード横取り攻撃:鍵を配送する郵便屋さんが悪人だったら?

OAuth 2.0の仕組みを想像してみてください。ユーザーが「Googleアカウントでログイン」ボタンを押すと、Googleが「認可コード」という一時的な鍵を発行します。このコードをあなたのアプリが受け取り、「本人確認完了!どうぞ!」と中に入るのが一般的な流れです。

しかし、この「認可コード」がアプリに届くまでの道中、悪意ある第三者が待ち構えていたらどうでしょう?

  • 攻撃の流れ:

1. 攻撃者は、あなたのアプリのふりをしてユーザーを罠にかけます。
2. ユーザーが認可コードを受け取った瞬間、攻撃者がそのコードを横取り(インターセプト)します。
3. 攻撃者はそのコードを使って、ユーザーになりすましてあなたのアプリにログインしてしまいます。

まるで、「鍵を宅配便で送っている最中に、偽の配達員が抜き取って本物の家に入ってしまう」ようなものです。これでは、どんなに頑丈な鍵を持っていても意味がありませんよね。

—

2. PKCEの登場:鍵に「特殊な仕掛け」を施そう

この「横取り」を防ぐために生まれたのが、PKCE(Proof Key for Code Exchange)です。読み方は「ピーシーケーイー」。ちょっと難しそうですが、仕組みはシンプルです。

先ほどの「鍵の配送」に、「合言葉」を追加するイメージです。

1. 準備段階: あなたのアプリは、ログインを開始する前に「秘密の合言葉(Code Verifier)」を作り、それをぐちゃぐちゃに変換したもの(Code Challenge)を先にサーバーへ送っておきます。
2. 鍵の受け取り: 認可コードが届きます。
3. 照合: アプリは認可コードと一緒に、隠しておいた「秘密の合言葉」をサーバーに送ります。
4. 判定: サーバーは「さっき預かった合言葉の変換元と、今届いた合言葉が一致するな。じゃあ横取りしたやつじゃないね!」と判断します。

攻撃者は、最初の「準備段階」を見ていないので、正しい合言葉を知ることができません。これで、コードを盗まれてもログインは成立しなくなります!

—

3. 実装のポイント:PKCEを組み込む

では、実際にどう実装するか、流れをコードのイメージで見ていきましょう。

手順1: 合言葉の生成(クライアント側)

まずは、ランダムな文字列(Code Verifier)を作り、それをSHA-256でハッシュ化して変換したものを用意します。

// 秘密の合言葉(ランダムな文字列)
const codeVerifier = generateRandomString(64);

// それを変換したもの(Code Challenge)
const codeChallenge = base64UrlEncode(sha256(codeVerifier));

手順2: 認可リクエスト(サーバーへ送る)

認可画面に飛ばす際に、code_challengeを忘れずに付与します。

GET /authorize?
response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=YOUR_CALLBACK_URL
&code_challenge=変換した合言葉
&code_challenge_method=S256 // SHA-256を使うよと宣言

手順3: トークン取得(答え合わせ)

認可コードを受け取ったら、元のcode_verifierを添えてトークンを要求します。ここでサーバーが照合を行い、正しければログイン成功です!

—

4. なぜ「PKCE」が必須なのか?

昔は「サーバーサイドで動くアプリなら、秘密鍵を隠せるから大丈夫」とされていました。しかし、今のWeb開発では、ブラウザ上で動くJavaScript(SPA)やスマホアプリが主流です。これらは「秘密鍵」を隠し持っておくことができません。

「誰でもソースコードが見れる環境では、鍵を隠し持てない。だからこそ、その都度『合言葉』を発行して安全を担保する」という考え方がPKCEです。

一歩ずつ対策を学ぶために

  • 「とりあえずPKCEを使う」: 今のOAuth 2.0実装では、PKCEは「推奨」ではなく「必須」です。ライブラリを使う際も、usePkce: trueといった設定が必ずあるはずです。
  • ログをチェック: 認証のリクエストにcode_challengeが含まれているか、ブラウザのデベロッパーツールで確認する癖をつけましょう。

—

最後に:セキュリティは「疑うこと」から始まる

セキュリティエンジニアとして一番伝えたいのは、「自分のシステムは常に狙われている」と仮定して設計することの重要性です。

「便利だから」「みんなこうしているから」で済ませるのではなく、「もし郵便屋さんが悪人だったら?」「もし鍵が盗まれたら?」と一歩立ち止まって考える。その視点こそが、あなたを一流のエンジニアにする第一歩です。

PKCEの実装は、最初は少しややこしく感じるかもしれませんが、一度理解してしまえば、あなたのアプリの信頼性を大きく高める強力な武器になります。ぜひ、今日から自分のコードを見直してみてくださいね。応援しています!

コメント

タイトルとURLをコピーしました