OAuth 2.0・OIDCの見るべきポイントを的確に抑えることがセキュアな認証を実現するコツ
OIDC(OpenID Connect)はOAuth 2.0の拡張仕様であるためフローなど共通点が多くあります。
そのため、セキュリティの注意すべき箇所も共通点が多いため共通点をまとめながら的確に理解していくことで悪用の隙を作らせないためのポイントとなります。
OAuth 2.0・OIDCへの代表的な攻撃はリプレイ攻撃やCSRFなど色々とありますが今回まだまだ世の中的に浸透していない以下3つにフォーカスしたいと思います。
1.認可コード横取り攻撃
2.コードインジェクション
3.トークンインジェクション
なぜこの3つかというと攻撃シナリオをしっかり想定しないで開発を進めると修正の出戻りがかなり大きいからです。
この辺りは設計段階で指摘する必要があるので設計段階のセキュリティレビューやSecure By Designといったシフトレフトの観点が大事になります。
OAuth 2.0・OIDCへの攻撃の対策は設計時点で対応しておく必要がある
OAuth 2.0・OIDCの共通点や相違点を比較しながら捉える
まずはOAuth 2.0・OIDCを理解ましょう。とにかく用語が多いので「これとこれは同じなのか」と整理比較しながら進めていきましょう。
OAuth 2.0はアクセストークンを発行する仕組み、OIDCはID トークンを発行する仕組みということなのでIDトークンの部分が気になりますね。
IDトークンとは識別に基づきアクセス者が認証されたという事実とそのユーザーの属性情報を結びつける、ID連携を実現するトークンです。
クライアントID・クライアントシークレットがクライアントサイドかサーバサイドかで、前者を安全に秘匿できる「コンフィデンシャルクライアント」後者を安全に秘匿できない「パブリッククライアント」と呼ばれます。そして、コンフィデンシャルクライアントの場合は認可コードフロー、パブリッククライアントの場合はインプリシットフローとなります。
まとめると
コンフィデンシャルクライアント | パブリッククライアント | |
---|---|---|
特徴 | クライアントID・クライアントシークレットを安全に秘匿できる | クライアントID・クライアントシークレットを安全に秘匿できない |
クライアントID・クライアントシークレットを扱う場所 | サーバサイド | クライアントサイド |
フローの名前 | 認可コードフロー | インプリシットフロー |
フローが共通しているにも関わらず認可レスポンス、認証レスポンスのように用語が微妙に異なりますがフロー上の登場人物も同様に以下のように共通しています。
OAuth | OIDC | 何を指すか |
---|---|---|
リソースオーナー | エンドユーザ | 利用者 |
クライアント | リライング・パーティ | 利用者に面しているアプリケーション |
認可サーバ | ID プロバイダ | トークンを発行するところ |
リソースサーバ | UserInfoエンドポイント | データや機能を提供するサービス |
OAuth 2.0とOIDCの言い換えの関係を頭に入れておくと何が共通しているのか明確になる
OAuth 2.0・OIDCで狙われる3つの攻撃と対策を理解する
1.認可コード横取り攻撃
同じカスタムスキームを持つアプリに認可コードを奪われ、アクセストークンを不正に取得する攻撃です。
なぜそんなことができるかというとカスタムスキームはどこかで一意になるように管理されているわけではないので同一のカスタムスキームはいくらでも作れてしまうからです。
カスタムスキームを根拠に認可コードを渡すのは危険とわかりました。では対策はというとPKCE(Proof Key for Code Exchange)です。
PKCEはまず認可リクエストのパラメータにcode_challengeとcode_challenge_methodを追加し認可サーバが保持します。
そしてトークンリクエストのパラメータにcode_verifierを追加し、認可サーバがこれを検証するという仕組みです。
流れから判るようにインプリシットフローでは対策できないので、スマホアプリは認可コードフロー+PKCEとすべきということです。
2.コードインジェクション
リダイレクトプロセスでを認可コードを第三者の未使用の認可コードに入れ替え攻撃者自身の管理下にあるアプリに適用する攻撃です。
これも対策はPKCE(Proof Key for Code Exchange)が有効になります。
3.トークンインジェクション
第三者の有効なアクセストークンを攻撃者自身の管理下にあるアプリに適用し、不正アクセスを行う攻撃です。コードインジェクションとはインジェクションするのがコードかトークンかの違いです。
実はOAuthに関しては認可サーバーが独自に対応していない限り対策が打てません(Googleはtokeninfo APIを提供しているのでGoogle系は対策可能)
一方、OIDCはat_hashで対策が可能です。
そもそもなぜそんな攻撃ができるかというと攻撃者も正規のサービス提供者も共通の認可サーバを介してリソースサーバへ認可させる実装ができるからです。
at_hashは認可を行う先だけでなく、認可を行う元との関係を検証できるハッシュをつけ検証できるようにした仕組みです。
スマホ問わずOIDC認可コードフローを採用しPKCEとat_hashを組み込んでおけば3つの攻撃に対応できる
様々サービスの組み合わせで自社のサービスを実現するところが増えてきましたが、サービスの利用と悪用の境界が非常にあいまいになってきていることを自覚し、設計時点で気づかないと思わぬところが脆弱になりサービスに致命的な不利益を発生させるかもしれません。
以上です。お役に立ちましたら幸いです。