OpenID Connect(OIDC)をデジタル認証アプリを題材に説明してみようと思います。
また、デジタル認証アプリを使用したアプリケーション開発の事例が少なかったので、これからデジタル認証アプリを利用する方の参考にもなれたらと思います。
前提
- デジタル認証アプリの認証方式を採用しています
- アーキテクチャはネイティブアプリとBFFの構成としています
- OAuth2.0の認可コードフローに則っています
基礎知識
デジタル認証アプリとは
「デジタル認証アプリ」は、マイナンバーカードを使った認証や署名を、安全に・簡単にするための、デジタル庁が提供するアプリです。行政機関や民間事業者は、デジタル認証アプリと連携するAPIを活用することで、マイナンバーカードを使った本人確認・認証や電子申請書類への署名機能を簡単に組み込むことができます。
(行政機関等・民間事業者向け実装ガイドライン より引用)
ワ方式とは
マイナンバーカードの署名用電子証明書を取得する手法。対象書類がマイナンバーカードに限られますが、ユーザーの操作時間が短い上に、偽造耐性が極めて高い特徴があります。また、電子証明書の失効情報を取得することで、最新の情報かどうかを確認することができます。
(民間事業者向けデジタル本人確認ガイドラインについてより引用)
OpenID Connect(OIDC)とは
ここではOIDCの説明は省きます。
よく分からない方はこちらがおすすめです。
RPとは
本稿で度々登場するRPについての説明も載せておきます。
RPは「Relying Party」の略称で、OIDC(正確にいうとID Tokenやアイデンティティ情報)を提供される側のことを指します。
平たくいうと、皆さんが開発するサービスのことです。
それとは逆に、OIDCを提供する側(本稿でいうデジタル認証アプリサーバ)をOpenID Provider(OP)と呼びます。
シーケンス図(全体)
認証開始からアクセストークンでデジタル認証アプリ(OP)のリソースへアクセスできるようになるまでのシーケンス図になります。
デジタル認証アプリ公式が出しているシーケンス図より具体性を持たせています。
次の章で、シーケンス図に記載されている検証のうち、初見では理解が難しいであろう脆弱性対策に絞って説明します。
脆弱性対策
関連するパラメータ | 防ぎたい攻撃 | 検証者 | 検証方法 | |
---|---|---|---|---|
stateの検証 | ・state | CSRF | RP | RPが発行したstateとデジタル認証アプリ(OP)が返却した認可レスポンスのstateが一致するか |
nonceの検証 | ・nonce | 認可コードインジェクション | RP | RPが発行したnonceとデジタル認証アプリ(OP)がトークンエンドポイントで返却したIDトークンのnonceとが一致するか |
code_verifierの検証 | ・code_verifier ・code_challenge ・code_challenge_method |
CSRF 認可コードインジェクション |
デジタル認証アプリ(OP) | RP(ネイティブアプリ)が認可エンドポイントにアクセスする際に使用したcode_challengeがRP(サーバ)で発行したcode_verifierから生成されたものか |
stateの検証
CSRF攻撃は、攻撃者が正規ユーザにフィッシングなどの手段で攻撃者が発行した認可エンドポイントにアクセスさせ、正規ユーザに意図しない操作を行わせる攻撃です。
正規ユーザが知らずのうちに攻撃者のリソースにアクセスして、情報を流出させてしまう危険性があります。
上記の攻撃は、結果反映APIで認可コードの発行者を識別できないために発生します。
そしてstateは、認可コードの発行者を識別するためのものです。
具体的には、認証開始APIで発行したstateをユーザ(もしくはセッション)に紐付けて保存しておき、その後の認可レスポンスを受け取った際にstateが一致するか検証することで防ぐことができます。
nonceの検証
認可コードインジェクションは、攻撃者が認可コードを横取りする攻撃です。
認可コードはアクセストークンを取得するためのものであり、アクセストークンを取得するためには認可コードをトークンエンドポイントに送信する必要があります。
そのため、認可コードを盗み出されると、攻撃者に正規ユーザのリソースにアクセスされる危険性があります。
上記の攻撃は、認可リクエストの送信者と認可コードの受信者を識別できないために発生します。
そしてnonceは、認可リクエストの送信者と認可コードの受信者の一致を確認するためのものです。
そのため、認証開始APIで発行したnonceをユーザ(もしくはセッション)に紐付けて保存しておき、その後のトークンエンドポイントを叩いた際にIDトークンに含まれるnonceと一致するか検証することで防ぐことができます。
code_verifierの検証
code_verifierの検証は、CSRF攻撃と認可コードインジェクションを防ぐために行います。
stateとnonceと異なる点は、検証者がデジタル認証アプリ(OP)であることです。
下記のシーケンス図は認可コードインジェクションの攻撃を想定しています。
攻撃者が認可コードを盗み出しても、code_challengeがcode_verifierから生成されたものでないとOP(デジタル認証アプリサーバ)は認可コードをアクセストークンに交換しないため、攻撃を防ぐことができます。