Upgrade to Pro — share decks privately, control downloads, hide ads and more …

認証認可を通して学ぶ、『わからない』のつぶし方 - ID沼入口 発表資料

Avatar for calloc134 calloc134
June 27, 2026
95

認証認可を通して学ぶ、『わからない』のつぶし方 - ID沼入口 発表資料

“ID沼入口” - 基本とセキュリティから始める、考え続けるためのID管理技術勉強会 で発表を行う資料です。
現在作成中のため、変更のある可能性があります。

https://openid.connpass.com/event/396041/

Avatar for calloc134

calloc134

June 27, 2026

More Decks by calloc134

Transcript

  1. かろっく @calloc134 右下の QR からプロフィールへ → 自己紹介 Web アプリとセキュリティ が好きな社会人一年生

    フロントエンドは React + TypeScript バックエンドは Hono などをよく触る。最近はお仕事でGoやPHP 基本的にWebアプリ・クラウドネイティブ・コンテナ周りに興味がある 認証認可・Web セキュリティの沼 に片足を突っ込み中 Zenn で OAuth/OIDC のデジタルブックを執筆中 @calloc134 2
  2. 対象とする人 → 一度は OAuth/OIDC の学習に挑戦したことがある人 話すこと 認証認可プロトコルの学習はなぜ苦しい のか その苦しさをどうほどく のか

    理解をどう実際の防御に活かす のか 一通り読んだけど、表面をなぞっただけで腹落ちしていない と感じる 仕様をちゃんと理解することで、どう実際の防御に活かせるのか を知りたい @calloc134 3
  3. S E C T I O N / 0 1

    苦しいポイントと 解決策の全体像 @calloc134 5
  4. OAuth/OIDC の学習で 多くの人がハマるポイントは大きく 2 つ 今日はこの 2 軸 で話を進めていく 苦しいポイントは大きく

    2 つ 構造的にムズい 概念同士の依存関係が複雑 用法を捉えるのがムズい 仕様の目的が見えづらい @calloc134 6
  5. S E C T I O N / 0 2

    学習の「歩き方」を 工夫する @calloc134 10
  6. ある概念を理解するために 別の仕様を前提 としていることが多い 例: 「Q. 認可コードフローは何故認可コードを挟むのか?」の答えを探す場合 → Implicit Flow の存在、クライアントタイプの違い、フロントチャネルのリスク、PKCE

    の仕組み… ここまで履修してようやく最初の質問に答えることが出来る → 学習順序が難しい 学習順序を工夫し、出来るだけ循環参照が発生しないようにうまく歩く ことが重要 それでも循環参照が避けられない部分は 「伏線」として捉え、後で回収 依存関係の複雑さ @calloc134 12
  7. おすすめの歩き方を一言で言うと、この 4 ステップ おすすめルートの全体像 登場人物 をつかむ リソースオーナー / クライアント /

    認可サーバ / リソースサーバ 素直な 1 本を追う まずは Confidential Client の認可コードフローだけを見る 攻撃と防御を知る state や PKCE を、どんな攻撃から守るためのものかから理解する 差分を広げる Public / Implicit / OIDC は後から差分として足していく @calloc134 13
  8. おすすめのルート 具体的な歩き方 (1) OAuth の登場人物を理解する 1 OAuth の素直な例を理解する 2 ここで考えないこと

    認可コードフロー以外のフロー Confidential以外のクライアント どういう攻撃があるのかを理解(一周目) 3 認可リクエスト側 トークンリクエスト側 ここでPKCEがようやく登場 @calloc134 14
  9. このルートなら、循環参照が少なくつまづきにくい 具体的な歩き方 (2) クライアントタイプの違いを理解する 4 Confidential / Public Publicに対する攻撃を理解する(二周目) 5

    認可コードフロー以外のフローを理解する 6 Implicit Flow ここでようやく、非推奨の理由が理解できる OIDC に進む 7 アクセストークンとIDトークンの用途の違い JWTに関する仕様 後は OAuth と同じように認可コードフローを辿る @calloc134 15
  10. ルートを組まず、いきなり最初から理解しようとした場合 例: いきなり Implicit Flow から理解しようとすると 前提が揃っていない場所に踏み込むと詰む → だからこそ、循環参照が起きない順序 を組んでから歩く

    ルートを外れるとどうなるか 非推奨の理由を知るには、クライアントタイプ やフロントチャネルのリスク の理解が前提 前提を調べに行くと、その先にまた別の「まだ知らない概念」 が待っている 循環参照にはまり、読んだはずなのに何も積み上がらない 結果、いつまでも同じ場所で躓いたまま 学習が進まない @calloc134 16
  11. S E C T I O N / 0 3

    用法をきちんと捉える @calloc134 18
  12. 実装を 目的という軸 で読み解けるようになる 例: OAuth と OIDC のプロトコルの意図の違い 目的からズレた構成があると違和感 として浮かび上がる

    「ID連携を行いたいのに、OAuth の仕組みを採用してしまっているな」 用法理解を深めることで、目的のズレを違和感として捉えられる ようになる そもそも、なぜ用法理解が大事なのか OAuth を見たとき → 「これはリソース認可 かな?」 OIDC を見たとき → 「これはID連携 かな?」 @calloc134 20
  13. 最初から実務の構成で理解しようとすると、混乱する OAuth の素直な例 → リソースに対する認可 例: Googleフォトに保存している写真を、印刷サービスに渡す OIDC の素直な例 →

    外部サービスのユーザ情報を用いたログイン(ID連携) 例: Googleアカウントで別サービスにログインする 想定するアプリは Rails のような サーバ上で動作する Web アプリケーション が良い フロントエンドがなく、Confidential Clientとなり OAuth/OIDC の本質に集中 できる 素直な例から理解する @calloc134 22
  14. 特に、フロントエンド界隈の人間が目にしがちな実装 初学者目線だと そもそも OAuth の不適切な用法、イレギュラーな例 この構成を参考にせず、素直な例から学ぶことが大事 逆に、ひねくれた例とは Auth0 や Firebase

    などの IdP を利用 フロントエンドからアクセストークンを取得 フロントエンドからバックエンドにアクセストークンを渡し、アクセストークンを使ってログイン状態を管理 技術上は OAuth だが、リソース認可ではなくログイン用途に見えてしまう → 「OAuth で認証していいの?」 初学者を苦しめる概念 (OAuth/OIDC の違い、Public Client、アクセストークンやPKCEの理解…) @calloc134 23
  15. 無意識のわからないからくる違和感を 「モヤモヤ」 と呼んでいく まずモヤモヤを質問の形に変換して吐き出せるかどうか が、わからないを潰す上で重要なポイント 例: 「認可コードフローってなんかややこしくない…?」 モヤモヤ… → 「モヤモヤ」から質問をうまく言語化できた

    この作業は難しいので、繰り返して慣れるしかないかも… まず「モヤモヤを吐き出す」をうまくなる なんでモヤモヤするんだろう? 1 登場人物が多いから?それとも矢印が多く見えるから? 2 なんでこの矢印が多いんだろう? 3 認可コードが挟まってるからかな? 4 「アクセストークンをそのまま返せばよいのでは?」 5 @calloc134 25
  16. おすすめ: GPT 5.5 Extended Thinking の Web検索 個人的な感触だと ChatGPT Plus

    を契約して質問しまくるのが一番確実 質問の答えだけでなく、「モヤモヤを言語化する」というプロセス自体の練習になる AIの回答は鵜呑みにしすぎないこと! 必要に応じて仕様で裏取りすること はやはり重要 わからないの潰し方(1): とりあえずAIに質問する @calloc134 26
  17. AIに質問した後で裏取りをする段階で、仕様や書籍が確かな情報源となる 一番良いのは仕様を読むこと ただ、関連仕様は大量にあり (RFC6749 / RFC9700 / RFC6750 / RFC7636

    …) 通読はしんどい そんなときは書籍で裏取りするだけでも良い と思う(個人的意見) おすすめ書籍 この3つでとりあえず大丈夫! ritouさんの監修付きで安心! わからないの潰し方(2): 仕様や書籍で裏取りする Auth屋さんのシリーズ 雰囲気OAuth本 OAuth/OAuth認証/OIDCの違い本 OAuth/OIDCへの攻撃と対策本 @calloc134 27
  18. このセクションの地図 (再掲) なぜ用法理解が大事なのか 実装を目的という軸 で読み解けるようになる 目的からズレた構成が違和感 として浮かび上がる 用法理解を深めるためのコツは 2 つ

    素直な例から学ぶ (ひねくれた例は避ける) 1 わからないを徹底的に潰す (モヤモヤの言語化 → AI・書籍・マサカリで裏取り) 2 @calloc134 29
  19. S E C T I O N / 0 4

    用法理解が効いてくる リアルワールド実装 @calloc134 30
  20. Hono という サーバサイドTypeScriptフレームワークの OAuth/OIDC に関連のあるミドルウェア実装を例にセキュリティを読み解く。 ※ Hono: JavaScript上で動作するサーバサイド TypeScriptフレームワーク Express.js

    のような立ち位置だが、よりモダンな設計思想を取り入れており近年人気が高まっている ここから先の話は仕様を理解していることが前提となるので、 勉強中の人は「仕様を理解しているとわかるんだな」と思ってもらえれば良い 前提 @calloc134 32
  21. 1 つ目の主張「違和感に引っかかれる」の実例 Hono JWK Middlewareにおいて CVE-2026-22818 として報告された脆弱性 alg パラメータのない JWK

    が存在した場合 ユーザがJWTの alg を指定でき、任意のJWTを偽造できてしまう という脆弱性 ※ 実際は WebCrypto の importKey() がエラーで落ちるので悪用は確認されず (1) Hono JWK Middleware の脆弱性 @calloc134 33
  22. 根本原因は、ユーザから渡される JWT の alg を信頼してしまっていたこと → alg にホワイトリスト形式を採用し、フィルタリングを行うことで解決 JWTの alg

    は、実はユーザが指定できるパラメータ 扱い 外界からの入力 であり、信頼してはいけない しかしこの感覚は、 alg の用法 まで深く理解していないとなかなか気づけない難しい部分 JWK Middleware の脆弱性の原因 alg を見てアルゴリズムを決定 1 この時点では署名検証は行われていない ユーザが指定したアルゴリズムで署名検証を行う 2 @calloc134 34
  23. 2 つ目の主張「より優れた解決策を選べる」の実例 フレームワーク側の脆弱性ではないが、OAuth/OIDC の深い理解が必要 な設定ミス問題 IdP + SPA + バックエンドAPIの構成で、

    バックエンドAPIがJWTのaudを検証していない場合、異なるAPIへのJWTでもAPIアクセスが出来てしまう という問題 (攻撃者が作成した別アプリ用のJWTでも受け入れるため、攻撃者のアプリにログインしたユーザになりすますことが 出来る) ※ 実際は多くのIdPでテナント分離されているので一定の保護はされるが 同一テナントの場合は危険 (2) Hono JWT Middleware の設定ミスによる問題 @calloc134 35
  24. JWT Middlewareの設定に aud の検証を行うオプションを忘れると発生 → JWTで aud を検証していなければ 攻撃者の作成した別アプリAPI用のJWTでも受け入れてしまう ことに

    JWT Middleware の設定ミスの原因 aud : JWT形式のアクセストークンにおいて、どのリソースサーバ向けのトークンかを示すパラメータ IdP + SPA + バックエンドAPIの構成では バックエンドAPI = リソースサーバ つまり aud = バックエンドAPIの識別子である必要がある @calloc134 36
  25. そもそも IdP + SPA + バックエンドAPIの構成で、アクセストークンをセッション代わりに使うのは 良くない そもそもこの構成は良くない 慎重に扱わないと今回のように JWT検証の設定ミスによる脆弱性

    が発生する SPAがOAuthクライアントとして動作するため、Public Client 扱い しかし OAuthでは出来るだけ Confidential Client を使うことを推奨 この用法は「APIリソースを認可する」というより 「外部のアカウント情報を連携してバックエンドAPIにログインする」ためにOAuthを利用している この用途ならそもそもID連携用に作られた OIDC の IDトークンを使う方が適切 @calloc134 37
  26. より良い解決策: バックエンド側APIで OIDC の IDトークンを検証しログイン実装 SPA と APIの通信は アクセストークンではなく httpOnlyなセッションCookie

    を使う 用法に沿った選択をすると、自然と防御も強くなる 、という典型例 (冒頭で約束した 2 つ目の主張の実例) ※ 余談: セッションCookieを利用するため、CSRF対策は必須 じゃあどうすべき? 認可のためのOAuthではなく ID連携のためのOIDCを使う → より意図に沿った選択 Public Client ではなく Confidential Client を使う → より安全な構成 SPAとAPIの通信はアクセストークンではなく httpOnlyなセッションCookie を使う → 悪性なスクリプトからのアクセスを防ぐ (副次的効果) @calloc134 38
  27. 用法をしっかり理解していると、違和感に引っかかれる → 「本来はこう使うはず」という基準とのズレが違和感になる  実例: JWK Middleware の脆弱性 ( alg は本来ユーザ入力扱いのはず)

    用法を深く理解していると、より優れた解決策を選べる → 「そもそも何がしたいのか」から道具を選び直せる  実例: aud 未検証の構成 → ID連携が目的なら OIDC を選ぶ このセクションのまとめ @calloc134 39
  28. S E C T I O N / 0 5

    まとめ @calloc134 40
  29. 本スライドのまとめ 苦しいポイントは大きく 2 つ 1 構造がムズい 用法を捉えるのがムズい それぞれへのアプローチ 2 学習の

    「歩き方」を工夫する 素直な例 から学び、わからないを潰す 用法を腹落ちさせることで 3 違和感に素早く気付ける より優れた解決策 を選択できる @calloc134 41