はじめてのOkta Workforce Identity Cloud (WIC) [第4回] 「Phishing resistant」って何だ?
本記事では、Okta Workforce Identity Cloud (以降、Okta WIC) での「Phishing resistant (フィッシング耐性)」について解説します。
Security > Authentication Policiesで、Rule内のTHEN以下の設定を見ると「Phishing resistant」というチェックボックスがあります。
これを有効にすれば「フィッシング攻撃に耐えられるものだけを認証に使う」という指定なんだな、ということは名称から想像がつくと思います。
また、Oktaドキュメントの「フィッシング耐性のある認証」には、FastPassとWebAuthnとの記載があるので、「それらを使えば、フィッシング攻撃に耐えられるんだな」ということまでは分かります。
言い換えますと、このPhishing resistantを有効にすると、このRuleにおいては、それら以外の認証器 (オーセンティケーター) は使えなくなる、例えばスマートフォンのOkta Verifyプッシュは使えなくなる、ということです。
「パスワードだけじゃダメなのはなんとなく分かるけど、スマートフォンのOkta Verifyプッシュを使ってもフィッシング攻撃を回避できないの?なんで?」というという疑問が沸きますよね?
そこで本ブログ記事では、その疑問解消の一助として、「Phishing resistant (フィッシング耐性)」について解説します。
以降の解説は、以下のブログ記事の内容を実施済み (理解済み) の前提で進めていきます。
- はじめてのOkta Workforce Identity Cloud (WIC) トライアル環境の構築
- はじめてのOkta Workforce Identity Cloud (WIC) [第1回] ユーザーと認証器の関係を紐解く
- はじめてのOkta Workforce Identity Cloud (WIC) [第2回] 多要素認証を紐解く
- はじめてのOkta Workforce Identity Cloud (WIC) [第3回] 「Hardware Protected」って何だ?
フィッシング攻撃とは
そもそもフィッシング攻撃とはどういうものなのか、順を追って説明していきます。
パスワードによる認証フロー (IdP-Initiated)
まずはシンプルに、ユーザー名とパスワードで認証が成功するまでの流れをご説明します。
アイデンティティプロバイダー (以降、IdP) であるOktaのドメインは、kaisha.okta.com とします。
サービスプロバイダー (以降、SP) は、app.atko.jp とします。
(1) ユーザーAは、Webブラウザで kaisha.okta.com へアクセスします。
(2) kaisha.okta.com から認証フォームが返ってきます。
(3) ユーザーAは、自身のユーザー名とパスワードを入力してSubmitします。
(4) 認証が成功すると、ユーザーAはHTTPステータスコード 302レスポンスでOktaダッシュボードへリダイレクトされます。
(5) kaisha.okta.com からユーザーAにOktaダッシュボードが返ってきます。
(6) ユーザーAは、SPである app.atko.jp にアクセスしたいので、app.atko.jp のアイコンをクリックします。
(7) 既にユーザーAの認証は完了しているので、その証として、kaisha.okta.com からはSAMLレスポンス (SAMLアサーション) がユーザーAに返ってきます。
このSAMLレスポンスには、kaisha.okta.com の秘密鍵による署名が付与されています。
(8) このSAMLレスポンスは、ユーザーAのブラウザで動作するJavaScriptによって自動的にSPである app.atko.jp へリダイレクトされます。(ユーザーAが何かアクションを起こす必要はありません。)
(9) SPである app.atko.jp は、SAMLレスポンスの署名をkaisha.okta.comの公開鍵で検証し、それが成功することで、「ユーザーAは kaisha.okta.com でちゃんと認証が成功したんだな」ということが分かります。
(10) 署名検証が成功したので、ユーザーAは app.atko.jp へのログインが許可されましたので、 app.atko.jp の画面がブラウザに表示されます。
以降、ユーザーAは、ユーザーAに許可された app.atko.jp 内のリソースへアクセスできるようになります。
フィッシング攻撃の成立 (パスワードだけの場合)
パスワードによる認証フロー (IdP-Initiated) をベースに、フィッシング攻撃の流れを説明します。
IdPであるOkta WICとユーザーの間に攻撃者が割り込む形でフィッシングが成立します。
攻撃者(=プロキシー)のドメインは kaisha.oktacom.io とします。
(0) 巧みな文章が記載されたフィッシングメールが攻撃者からユーザーAに届きました。ユーザーAは思わず、メールに記載されたURL: kaisha.oktacom.io をクリックしてしまいました。
(1) ユーザーAは、Webブラウザで kaisha.oktacom.io へアクセスしてしまいます。
(1x) 攻撃者は宛先URLを kaisha.okta.com に書き換えて、Okta WICに送ります = ユーザーAとして振る舞います。
(2) kaisha.okta.com から認証フォームが攻撃者へ返ってきます。
(2x) 攻撃者は、ユーザー名とパスワードが kaisha.oktacom.io に返ってくるように認証フォームを書き換えてユーザーAに送ります。
(3) ユーザーAは、自身のユーザー名とパスワードを入力してSubmitします。
(3x) 攻撃者は、ユーザーAのユーザー名とパスワードを kaisha.okta.com へ転送します。
(4) 認証が成功すると、攻撃者はHTTPステータスコード 302レスポンスでOktaダッシュボードへリダイレクトされます。
(5) kaisha.okta.com から攻撃者にOktaダッシュボードが返ってきます。
(6) 攻撃者は、SPである app.atko.jp にアクセスしたいので、app.atko.jp のアイコンをクリックします。
(7) 既にユーザーAの認証は完了しているので、その証として、kaisha.okta.com からはSAMLレスポンス (SAMLアサーション) が攻撃者に返ってきます。
このSAMLレスポンスには、kaisha.okta.comの秘密鍵による署名が付与されています。
(8) このSAMLレスポンスは、攻撃者のブラウザで動作するJavaScriptによって自動的にSPである app.atko.jp へリダイレクトされます。(もしくは、攻撃者のプログラムで転送されます。)
(9) SPである app.atko.jp は、SAMLレスポンスの署名をkaisha.okta.comの公開鍵で検証し、それが成功することで、「ユーザーAは kaisha.okta.com でちゃんと認証が成功したんだな」ということが分かります。
しかし、実際にはユーザーAではなく、攻撃者です。
(10) 署名検証が成功したので、ユーザーAは app.atko.jp へのログインが許可されましたので、 app.atko.jp の画面がブラウザに表示されます。
しかし、実際にはユーザーAではなく、攻撃者です。
===== << Tips >> =====
イメージ図が複雑になってしまうので省略しましたが、実際には、攻撃者は(4)以降の処理をユーザーAにも送るはずです。
そうしなければ、ユーザーAに「あれ?認証は間違っていないはずなのに、通信が止まったな。なんかおかしいな。。。」と気づかれてしまうので。
攻撃者はできる限り自身の存在に気づかれたくないはずですので、ユーザーAには、普段通りの処理が行えているように見せかけるはずです。
================
フィッシング攻撃の成立 (パスワード+スマートフォンのOkta Verifyプッシュの場合)
上記の「フィッシング攻撃の成立 (パスワードだけの場合)」の流れに、スマートフォンのOkta Verifyプッシュを加えるとどうなるかを説明します。
(0)〜(3x) までの流れは変わりません。
(3a) パスワードでの認証が成功すると、2要素目としてのOkta Verifyプッシュのリクエストが、kaisha.okta.com から直接スマートフォンに到着します。
なので、スマートフォンのOkta Verifyアプリは、ユーザーAのWebブラウザが今どこにアクセスしているのかを知ることができません。
(3b) ユーザーAは、(1), (2x), (3) の流れで、普段通りOkta WICの認証を行っていると思い込んでいるので、スマートフォンのOkta Verifyに通知がくれば、普段通りプッシュしてしまうでしょう。
(3c) kaisha.okta.com は、正常なOkta Verifyプッシュのレスポンスを、スマートフォンのOkta Verifyから直接受け取ります。
この時も、スマートフォンのOkta Verifyアプリは、ユーザーAのWebブラウザが今どこにアクセスしているのかを知らないままです。
結果、Okta Verifyプッシュは攻撃者 (プロキシー) の存在を知ることなく、普段通り動作するので、認証が成功します。
以降の(4)〜(9)の流れは変わりません。
このように、スマートフォンのOkta Verifyプッシュを使っても、フィッシング攻撃が成立してしまいます。
フィッシング耐性とは
このようなフィッシング攻撃を回避するには、「ユーザーAのWebブラウザは今、kaisha.okta.com サイトで認証していないぞ!」ということに気づく仕組みが必要です。
ユーザーA (=人間) がURLをしっかりチェックしてそれに気づければよいのですが、普段の認証画面とそっくりだったり、忙しかったり、疲れていたりすると、仮にセキュリティ意識の高い人であっても、100%気づくのは難しいでしょう。
よって、人間が頑張るという以外の方法で考えるべきですが、上記の通り、残念ながらスマートフォンのOkta Verifyアプリは、ユーザーAのWebブラウザとは独立した位置にいるので、Webブラウザが今、攻撃者 (プロキシー) に誘導されていることを知ることができません。
そこでFastPassの登場です。
FastPass機能を持つOkta Verifyは、Webブラウザが動作するデバイス内にインストールされるので、「今、Webブラウザが誰と通信しているのか?」を知ることができます。
それをOkta WICに伝えることで、「あっ! ユーザーのWebブラウザが今通信してる相手は、私じゃないぞっ!」とOkta WICが気づき、認証に失敗します=フィッシング攻撃が成立しません。
どういうことか、以降の認証フローを用いて説明します。
FastPassの認証フロー (やや詳細)
まずは、FastPassで認証が成功するまでの流れをご説明します。
こちらのブログ記事の「『FastPass』と『生体認証』の話」の章で、FastPassの動作イメージをお伝えしましたが、ここでは「なぜFastPassにはフィッシング耐性があるのか」を理解するために、FastPassの動作をもう少し詳細にお伝えします。
WindowsやMacにインストールされたOkta Verifyは、ローカル (127.0.0.1) のHTTPサーバとして起動しています。
TPM/Secure Enclaveは、WindowsやMacの中にあるハードウェアで、そこにOkta Verifyの秘密鍵を保管します。(TPM/Secure Enclaveについて少し理解を深めたい方は、第3回目の記事をご参照ください。)
(1) ユーザーAは、Webブラウザで kaisha.okta.com へアクセスします。
(2) kaisha.okta.com から以下のような認証フォームが返ってきます。
(3) 上記の「Okta FastPassでサインインする」をクリックすることで、kaisha.okta.com へチャレンジ (Nonce) の要求が送られます。
チャレンジ (Nonce) は、「一時的に利用するランダムな文字列」ぐらいにお考えください。
(4) Webブラウザは、kaisha.okta.com からチャレンジ (Nonce) の返答を得て、それをJavaScriptで自動的にOkta Verifyローカルサーバ (127.0.0.1) へ、HTTPで送ります。
そのHTTPリクエストには、Webブラウザが今どこにアクセスいていたのかを示すOriginヘッダが含まれており、その値は「https://kaisha.okta.com」です。
(並行して、Webブラウザからkaisha.okta.com に対して、認証が成功したかどうかの確認のためのポーリング が一定の周期で行われます。(図中の「ステータスのポーリング (一定周期)」))
(5) Okta Verifyローカルサーバは、TPMまたはSecure Enclaveにチャレンジ (Nonce) の署名を要求します。
(6) TPMまたはSecure Enclaveは、ユーザーAの秘密鍵でチャレンジ (Nonce) に署名し、Okta Verifyローカルサーバへ返します。
(7) Okta Verifyローカルサーバから直接 kaisha.okta.com に対して「チャレンジ (Nonce) の署名」と、Originヘッダ=「Origin: https://kaisha.okta.com 」を送ります。
(8) kaisha.okta.com は、「ユーザーAの公開鍵を使った署名の検証」と、「Originヘッダのドメインが自身のドメイン (=kaisha.okta.com) と一致するか?の確認」を行い、どちらもOKであれば、認証は成功です。
(9) 認証が成功したので、kaisha.okta.com は、Webブラウザからの一定周期で送られてくるステータスポーリングの返答として、認証成功を意味するトークン付きのURLをWebブラウザに返します。
(10) Webブラウザは、JavaScriptで自動的に上記(9)のURLにアクセスします。
(11)からの流れは、「パスワードによる認証フロー (IdP-Initiated)」の(4)からと同じです。
===== << Tips >> =====
上記(4)の、WebブラウザからのHTTPリクエストに含まれる「Originヘッダ」は、Okta独自のものではなく、「オリジン間リソース共有 (CORS)」という仕組みによるものです。
例えば、Webブラウザが今アクセスしているサイト (サイトA) からJavaScriptを受け取って、そのJavaScriptでそれ以外のサイト (サイトB) へアクセスするような場合には、そのHTTPリクエストにはOriginヘッダ (=サイトAのドメイン) を含むよう、CORSの中で規定されています。
================
FastPassによるフィッシング攻撃の検知
もうお気づきかと思いますが、フィッシング攻撃防御のポイントとなるのは Originヘッダ です。
ユーザーA側からOkta WIC側へ送られてくるOriginヘッダのドメインが kaisha.okta.com と一致しなければ、フィッシング攻撃とみなされます。
説明済みの内容から類推できると思われる部分は割愛して、ポイントだけお伝えします。
(4x) ユーザーAのWebブラウザは kaisha.oktacom.io と通信しているので、Okta Verifyローカルサーバへ送るHTTPリクエストのOriginヘッダの値は「https://kaisha.oktacom.io」になります。
(7) kaisha.okta.comへ送るOriginヘッダの値も当然ながら「https://kaisha.oktacom.io」です。
(8) kaisha.okta.comは、Originヘッダのドメイン「kaisha.oktacom.io」と自身のドメインが一致しないので、フィッシング攻撃と判断し、認証が失敗します。
(9) kaisha.okta.com は、Webブラウザからの一定周期で送られてくるステータスポーリングの返答として、認証が失敗したことを通知します。
このように、FastPassであればフィッシング攻撃を防御できます。
本ブログ記事ではWebAuthnにまでは言及しませんが、概ね同じ動き (Originヘッダで判断する) とお考えください。
Phishing resistant (フィッシング耐性)の動作確認
では、簡単にPhishing resistantの動作を確認しておきましょう。
第2回目の設定完了時の2つのユーザーの認証器 (オーセンティケーター) は以下のようになっていますので、これらのユーザーを使って確認します。
① [email protected]: 「スマートフォンのOkta Verifyプッシュ」
② [email protected]: 「FastPass」
Authentication PolicyのRuleで、Phishing ResistantをOFFにする
第2回目のブログ記事と同様に、RSA SAML Test Service Providerアプリを使って動作を確認することにします。
現在、Security > Authentication Policies で表示されるポリシーのうち、Any two factorsがRSA SAML Test Service Providerアプリと紐づいています。
Any two factors > Catch-all Rule の Actionsをクリックして表示されたEditをクリックします。
表示された以下の画面で、THENの下の「 [AND] Possession factor constraints are」で、以下のようにPhishing resistantを含む全てのチェックボックスをOFFにして、Saveします。
スマートフォンのOkta Verifyプッシュで認証(1) 〜Phishing resistant設定「なし」の状態〜
RSA SAML Test Service Providerアプリに、SP-Initiatedでアクセスします。
SP-Initiatedは、WICトライアル環境構築時にも行った、RSA SAML Test Service Providerアプリ側に表示された、以下のようなURLに最初にアクセスするパターンです。
Google Chromeのシークレットウィンドウを使うのが動作が分かりやすいので、そちらを使います。
[email protected] でログインします。
「プッシュ通知を受け取る」を選択します。
以下の左画面に遷移すると同時に、スマートフォンのOkta Verifyに通知が来ますので、「はい、私です」をクリックします。
今はPhishing resistant機能を無効にしているので、認証が完了して、RSA Test Service Providerにアクセスできます。
スマートフォンのOkta Verifyプッシュで認証(2) 〜Phishing resistant設定「あり」の状態〜
今度は、Phishing resistant設定を有効にして認証してみます。
結果を先に伝えると、ご想像通り、このユーザー ([email protected]) はフィッシング耐性のある認証器 (オーセンティケーター) を持っていないので、認証は失敗します。
Security > Authentication Policies > Any two factors > Catch-all RuleのActionsでEditをクリックします。
表示された以下の画面で、THENの下の[AND] Possession factor constraints are で、Phishing resistantのチェックボックスをONにしてSaveします。
===== << Tips >> =====
Phishing resistantを有効にすると、その下の「Exclude phone and email authentication」も自動的に有効になります。
Phone (電話) もemail (電子メール) も、フィッシング耐性を持っていないので、これらの「所持」要素は自動的に除外されるようになっています。
================
先の動作確認と同様に、SP-InitiatedでRSA SAML Test Service Providerアプリに[email protected]でアクセスしてみます。
結果、スマートフォンのOkta Verifyプッシュはフィッシング耐性を持っていないので、以下のように拒否されます。
FastPassで認証 〜Phishing resistant設定「あり」の状態〜
同様に、FastPassを持つ [email protected] でアクセスしてみます。
FastPassはフィッシング耐性があるので、RSA SAML Test Service Providerアプリにログインできます。
まとめ
本ブログでは、Phishing resistant (フィッシング耐性) 機能についてご紹介しました。
この機能によって、フィッシング耐性のない認証器 (オーセンティケーター) でのユーザー認証は拒否できるようになります。
外国から日本に届くフィッシングメールは、変な日本語のものであれば文章から判断できる場合が多いですが、最近の生成AIの進歩により、外国からでも違和感のない日本語のフィッシングメールが増えた、という話も聞こえてきます。
このような背景もあり、フィッシングは今後も脅威になり続けると考えられるため、特に機微な情報を扱うSaaSアプリケーションへアクセス時には、この機能を有効にして、フィッシング耐性のある認証器に限定するのが望ましいでしょう。
また、Okta WICでは、認証の強化だけでなく、管理者が行うユーザーの登録/変更/削除に関わる業務の自動化や、人事管理システムや既設ディレクトリなどとの柔軟な連携も可能です。
Oktaでは、これらの機能を体感頂くことができる「Okta Essentials」トレーニングをご用意しております。(日本語でのトレーニングもご用意しております。)
このトレーニングは全体像を体系的にご理解頂ける内容となっておりますので、是非ともご活用ください。