0x00 背景
転職しました。これを機にここ数年セキュリティエンジニアやってきた感想を書こうかなと思います。
私は副業を含め、主にWeb系事業会社のインハウスセキュリティに従事してきました(ベンチャー、上場企業、メガ企業の子会社など)。経歴はかなり限定的ですが、この文章のターゲットを従業員数50人から3000人程度のWeb系企業だと想定して書いています。
転職しました。これを機にここ数年セキュリティエンジニアやってきた感想を書こうかなと思います。
私は副業を含め、主にWeb系事業会社のインハウスセキュリティに従事してきました(ベンチャー、上場企業、メガ企業の子会社など)。経歴はかなり限定的ですが、この文章のターゲットを従業員数50人から3000人程度のWeb系企業だと想定して書いています。
2003年式のフェアレディZ Z33前期型を買ってから、ずっっっっと修理してしていた。別に買ったZが悪いわけではなく、出会ったメカニックが悪いのだ。
最初にZがのアイドリングが少し振動するから、Zの同好会で知り合ったメカニックさんが勤めてる工場(工場Aとする)に行ってみてもらったが、特にエラーコードもなく、原因わからないので、スパークプラグとカムポジセンサーの交換を進められた。それで、交換した当日に車を家まで運転してたら、途中でカップホルダーから煙が出て、車内に異臭が発生した。そしてエンジンチェックランプも点灯した。エンジンルームを開けて嗅いでも何も匂いしないからエンジンルームのどこか燃えてるわけではなさそうだ。煙の理由がわからないのでとりあえずエンジンのエラーコードをOBDで読んでみた:
楽待のシミュレーションツールが有料化になり、自作のシミュレーションツールを公開します。家賃収入、経費(利息、管理費、修繕費等)、減価償却、譲渡時の簿価、税率等を全部考慮した割と現実に近しいシミュレーションです。
下記のスプレッドシートにアクセスし、ご自身で不動産の各種データを入力していただき、結果をみてみましょう!
https://docs.google.com/spreadsheets/d/1iVdXmZYvdEj9ZVJnR0cJRibPFti_ZY8ATlPFOc0v8Sk/edit#gid=1336925682
firebase/firestoreの診断を行う時に、burpを使うと、下記のようなtimeoutエラーが出る。これの解決法をここにまとめる。
[2021-11-04T09:18:26.044Z] @firebase/firestore: Firestore (7.6.2): Could not reach Cloud Firestore backend. Backend didn't respond within 10 seconds.
This typically indicates that your device does not have a healthy Internet connection at the moment. The client will operate in offline mode until it is able to successfully connect to the backend.
具体的に、chromeのdevtoolでxxx.chunk.jsを開いて、 this.forceLongPolling
を見つけ、この行(36472)にbreakpointを仕掛ける。この行の実行が終わったら、forceLongPolling
の値をtrueにして実行を続ける。
略。
結論で言うと違いはとても簡単明瞭だ。stateパラメータで防ぎたいのはCSRF攻撃だ。OAuthの文脈でのCSRFは攻撃者のcode/tokenを被害者に強制使わせ、被害者を攻撃者の身分でログインさせる攻撃である。一方、nonceで防ぎたいのはtoken/code横取り攻撃。CSRFと逆で、token/code横取り攻撃は攻撃者が被害者のtoken/codeを取得し、被害者の身分になりすます攻撃である。
nonceはSPが発行して、idPがこのnonceを発行したtokenに入れる。SPがtokenをもらった時に、まずtokenに含まれたnonceをユーザーのsessionに記録したnonceと比較する。一致しない場合このtokenを破棄する。要するにtokenはユーザーのsessionと紐づいている。ここで気づいたかもしれないが、stateパラメータはユーザーのログイン状態としか紐づいてないので、nonceがわりにならない。
sessionを持っているSPだとnonceの検証はできるが、APIサーバーだと通常session持っておらず、来たtokenはそのまま信用するしかないがnonceの意味なくない?
好久没水文章了,水一篇。最近有工作需要使用Android Studio的Emulator来测试App,所以要将Emualtor的通信转发到PC上并由burp捕获。
问题是AVD的Emulator使用了它自己的虚拟路由,无法在PC上找到VM的interface,所以无法在PC上捕获Emulator的通信。
通过查阅资料 https://developer.android.com/studio/run/emulator-networking?authuser=1 发现AVD的Emulator会将发到10.0.2.2的通信转发到PC的loop back上,所以我们可以先将Emulator的所有通信转发到10.0.2.2,然后进一步在PC上将loop back的通信转发到burp上,操作如下:
一 Web Pentester の立場から、毎回 OAuth 連携の案件が来る時に、どこが診断する必要なのか、どこが idP の SDK 使っているから診断不要なのかを見極める必要があり、このような背景において、OAuth2.0 をもう一回復習して、心得を共有したいと思い始めました。(0x01~0x08)。復習しているうちに、OAuth の idP 両社の脆弱性を見つけ、50万円賞金もらって終わりと思ったらいつの間に両社経営統合されました。この話を読みたい方は 0x09 から読んでください。
この文章を読む前提は二つあります:
これを前提に、以下の六つの質問に対して議論してみます。この六つの質問の答えが全部わかる人は 0x09 に進めてください。
まず一番簡単だが、一番誤解が多い質問から説明します。
Code Grant では、code が何かしらの理由で攻撃者にもれた場合に (Auth Server が redirect 先を制限してない、Referer/URL で漏洩、Appの場合悪意 App Schema による漏洩等)、攻撃者がこの code を使って token と交換できるでしょうか。多くの方が「state パラメータがついていれば交換できない」という誤解を持っています。
しかし、state パラメータは code と紐づいてなく、攻撃者は code を入手したら、被害者の state を使わずに、自分が事前に用意した state と被害者の code で正規な URL を組み立てることができます。この URL を使えば被害者のアイデンティティーで認証を完結することができます。
まず Web Message Response Mode とは何がを説明します。これは普段 OAuth ではあんまり聞きなれない単語かもしれませんが、2015年に HTML5 が普及してから導入された Mode です。これはあくまで実装の話で、OAuth の 新しい Flow ではありません。Web Message Response Mode は Implicit Grant とも、Code Grant とも組み合わせて使えます。簡単にイメージを説明すると、今まで各 Flow を紹介する際に、idP が token また code を Client に返す時に、redirect を使って Client に token また code を URL 経由で渡していると説明したが、これは実は Redirect Response Mode と言います。この Mode に対して、Web Message Response Mode という Mode があります。 Web Message Response Mode では、redirect を使わずに、HTML5 の postMessage を利用しています。Client のサイトから OAuth 認証を実行する時に、idP サイトに遷移せずに、Pop-up Window が開かれ、その新しい Window で OAuth の認証をします。認証が完了したら、postMessage API を使って、親 Window (Client のサイト) に token または code を渡します。もっと詳しい説明はこちらの IETF に記述されています:https://tools.ietf.org/html/draft-sakimura-oauth-wmrm-00。
インタネット上では Redirect Response Mode の紹介が多いが、正直 Implicit Grant で Redirect Response Mode を使う idP は最近あんまり見かけず、例えば LINE はそもそも response_type=token をサポートしないし、Facebook と Google が提供している Login Widget (Javascript の SDK) は Web Message Response Mode を使ってます。
では、Web Message Response Mode を使っていると、かつて炎上していた Covert Redirect (この文章はわかりやすい:https://weblog.bulknews.net/covert-redirect-vulnerability-with-oauth-2-2c1f3083b1b4) という脆弱性はなくなるでしょうか?
答えは YES, Covert Redirect という脆弱性は無くなります。理由も自明ですが、Redirect という手順がなくなったからです。その代わりに postMessage が利用され、Open Redirector があっても OAuth への影響はないでしょう。
ここで少し余談ですが、なぜ LINE が Implicit Grant をサポートしないかというと、筆者の推測だと、OAuth Security Best Practice に書書かれているように、Implicit Grant に脆弱性がとても埋め込みやすい (token 漏洩しやすい、client の正規性確認できないなど) ので、おすすめしない Flow になっています。
0x02 で議論していた各 idP が提供している Web Message Response Mode の Javascript SDK を使う場合には、Client の実装不備による OAuth で良く発生する CSRF 脆弱性にも耐性があるでしょうか?
答えは YES, Web Message Response Mode を取り込んだ Javascript SDK を使うと、state パラメータはなくても CSRF はありえないでしょう。なぜかというと、idP が SDK をちゃんと実装していれば、message イベントが来る時に、postMessage の origin をチェックしているでしょう。この origin のチェックによって、非 idP の domain からの postMessage は一切拒絶されるので、CSRF の余地がありません。
ちなみに、Yahoo の Javascript SDK は親切に state パラメータを生成し、チェックしてくれていますが、Google と Facebook の Javascript SDK はいずれも state パラメータを使っていません。
Appの場合、悪意に登録された App Schema による Code Interception攻撃を防ぐために、Code Flow with PKCE という手法が採用されます。多くの idP が提供している SDK が、PKCE を実装する時に state パラメータも必須になっているが、実際に state パラメータがなくても(Clientの実装忘れ等)、CSRF に耐性あるでしょうか?
答えは YES, state パラメータがなくても、PKCE は CSRFに耐性があります。この答えにたどり着くまで少し考えが必要ですが、PKCE を使う場合に、code_challenge と code は idP サーバで紐づいていて、攻撃者は code_verifier が知らない限り、 自分の code を他人に使用させることはできません。
WebView を利用して、OAuth の認証 SDK を提供している idP がすくなくありません。むしろ WebView の中で OAuth 認証をさせるのはもう各 idP のデファクトスタンダードになっていると言えます。 Code / Token Interception という問題は Native App の OAuth 認証時に、外部ブラウザを使う時に発生し得る問題ですが、WebView を使う場合にも Code / Token Interception 攻撃発生し得るかみてみます。
Code / Token Interception が発生するタイミングは、OAuth の認証が完了し、 Client App に遷移して戻る時です。この際に違うクライアントに遷移してしまったら Code / Token Interception が発生します。ただし、Native App 用の WebView を使った SDK は、殆どの idP はその WebView の shouldOverrideUrlLoading メソッドを上書きし、認証完了後の Redirect を App 内に閉じるようにしています (e.g. Facebookの場合:https://github.com/facebook/facebook-android-sdk/blob/4.x-branch/facebook-common/src/main/java/com/facebook/internal/WebDialog.java#L578)。このような実装であれば、外部 App への誤遷移によって、 code / token が外部 App に漏れることはないでしょう。
しかし、他の idP も調べたら脆弱な実装は見つかりました。例えばヤフーの YConnect を使う場合に、ヤフーのライブラリーは WebView を改造することなく、認証成功後に Redirect する時に、App 本体から Export しているカスタムスキーマを利用して、WebView から App 本体に遷移させます。この状況は何が不味いかというと、WebView からカスタムスキーマをオープンする時に、必ずしも該当 WebView を開いた App が優先的に開かれる保証はないです。要するに、他の Evil-App も同じカスタムスキーマを登録したら、正規 App の WebView から Evil-App を開く可能性があります。これは Code / Token Interception に繋がります。
前述の事例から見ると、WebView を利用した Native App はどんな脆弱性も作り込めなく、最強な作り方では?と思ってしまう方も居ると思いますが、しかし、このデファクトスタンダードは本当にいいのか考えましょう。
RFC8252の8.12節で説明された通りに、WebView を使うとそもそも OAuth の意味が無くなります。OAuth は信用できない第三者に ID / PW を提供しないで身分を認証するプロトコルであり、第三者 App の中の WebView (WebView に偽装するものも含め) に直接 ID / PW を入れるのはどう考えても OAuth 本来の役目が成り立たないでしょう。
ここで LINE を褒めてあげたいんで、LINE の場合は WebView 方式の SDK を提供せずに、ちゃんと外部ブラウザ方式で認証をしています。
Y -- Clientの実装により、脆弱性を埋め込む可能性がある
N -- Clientの実装と関係なく、脆弱になることはない
脆弱性 | Implicit Grant | Code Grant | Code Grant with PKCE |
---|---|---|---|
Token Replace | Y | N | N |
Covert Redirect | Y | N | N |
CSRF | Y | Y | N |
Token Interception | Y | - | - |
Code Interception | - | Y | N |
この表から見ると、やはり Code Grant with PKCE は一番安全だなと感じますよね。
Identity Provider | Implicit Grant | Code Grant | Code Grant with PKCE |
---|---|---|---|
LINE | サポートしない | Client 各自で実装 | Native SDK |
Yahoo! Japan | Javascript SDK, Web Message Response Mode | Javascript SDK, バックエンドはClient 各自で実装 | サポートしない |
Javascript SDK, Web Message Response Mode | Client 各自で実装 | Client 各自で実装 | |
Javascript SDK, Web Message Response Mode | Client 各自で実装 | サポートしない |
Native SDK | Client の実装により脆弱を埋め込む可能性 | |
---|---|---|
LINE | PKCE | ない |
Yahoo | Implicit / Hybrid | 外部ブラウザを使う実装は Code Interception と Token Interception に脆弱;WebView を使う実装もカスタムスキーマ Export しているので脆弱になる;Stateパラメータはデベロッパー自ら生成するので、デベロッパーによってCSRF脆弱性が生じうる |
Implicit Grant | Google Sign-in 使うと Implicit Grant になるが、WebView をカスタマイズしているので Token Interception 攻撃されない。PKCE使おうとしたら自前でクエリを組み立てる必要がある。 | |
Implicit Grant | WebView をカスタマイズしているので Token Interception 攻撃されない |
Javascript SDK | Client の実装により脆弱を埋め込む可能性 | |
---|---|---|
LINE | ない | Client の実装による |
Yahoo | Implict Grant | Web Message Response Mode + state なので、Covert Redirect と CSRF 攻撃されない |
Implicit Grant | Web Message Response Mode なので、Covert Redirect と CSRF攻撃されない | |
Implicit Grant | Web Message Response Mode なので、Covert Redirect と CSRF 攻撃されない |
結論は意外と簡単にまとめられます。idP が提供している SDK を利用している場合に、Client の実装に関わらず脆弱になる可能性はほとんどないと言えます。ただし、idP の提供している SDK に脆弱性があったり、一部のパラメータ生成がデベロッパーに任せたりしたら話は違いますが。。。
例として、次の二段落で idP 側の脆弱性について紹介します。
まず今回5000ドルの報奨金をいただいたLINEのOAuthの脆弱性に付いて紹介します。とてもシンプルな脆弱性で、一言でいうと、PKCEの実装にcode_verifierとcodeの紐づけをAuth Serverでチェックしていないというところがダメです。
なぜこんな簡単な脆弱性は今まで見つかってないのかというと、おそらくこの PKCE 機能はドキュメントされていないからではないかと推測しています。LINE の line-sdk-android を実際に動かして通信みないと、LINE の OAuth が PKCE 対応していること自体に気づけないし、さらに、パラメータの名前は標準的な code_verifier と code_challenge ではなく、otp と otpId と名付けされて、一目ですぐ PKCE だと気づきにくいでしょう。(同社の情報によると、実装当時はまだ PKCE の標準が定めていないから code_verifier などの標準単語使わなかったわけだそうです。)
実際にこの脆弱性を利用するために、被害者アプリとおなじ package name の悪意アプリをインストールする必要があることです。悪用するには少しハードルがあると言えます。さらに、PKCE が実装されている Identity Provider 自体も少なく、Facebook でもそもそも PKCE 対応していないし、PKCE 対応しようとするだけで偉いと思います。ただし、ちゃんと実装しましょうね。
次の例は Yahoo の OAuth にあります。0x05にすでに少し触れてまして、簡単に説明すると、ヤフーの OAuth SDK は超手抜き実装で Callback 用のカスタムスキーマを Export されていて、WebView で認証しても、外部ブラウザで認証しても Code Interception, Token Intercetion ができてしまいます。外部ブラウザーを使う OAuth 認証の Code Interception と Token Interception は基本 PKCE でしか防げないので、単に PKCE 未実装だけだと脆弱性と言えるか微妙ですが、少なくとも WebView を使った認証フローは PKCE 無しでも Code Interception と Token Interception されない実装はできるはずです。Facebook も PKCE 未対応ですが、Facebook の SDK では WebView の shouldOverrideUrlLoading メソットをオーバライドすることで、Callback 時に外部アプリに遷移出来ないようにされています。一方でヤフーの手抜き実装だと WebView をカスタマイズしてなく、Callback の URL スキーマが来た時に OS の機能に頼ってどのアプリを立ち上げるのを任せている状態で脆弱です。
これの修正としてはまずカスタマイズスキーマ(Android の場合)を android-app:// スキーマに入れ替わって、その後根本的な対策 PKCE 実装を追加されたらしいです。
もう一つ気になることがります。OpenID Foundation は OpenID Connect Certification というプログラムがあって、この組織の特定の要件を満たすと、会社のサイトに認定されてるよ的なロゴを貼ることができます。要するにオンラインショッピングする時によく見かける SSL Site Seal Logo のようなもんです。ヤフー社のはこちらに貼られていますhttps://developer.yahoo.co.jp/yconnect/v2/。このロゴを見ると、すごい「セキュアだ!」と安心感が出るかもしれませんが、よくよくここの認定に関するドキュメントを読んだらhttps://openid.net/wordpress-content/uploads/2018/06/OpenID-Connect-Conformance-Profiles.pdf、セキュリティ上の要件は一つも書かれていません。結局 OIDC の Site Seal Logo があっても、どの程度の安全性をクリアしているのかを表明するものではありません。何を言いたいかというと、OIDC といえば認証認可という安全性は極力求められている分野のはずですが、OpenID Foundation で発行した Certification には安全性レベルの定義はないのはやや気持ち悪いです。
今回特に LINE と Yahoo で見つけた脆弱性の話しましたが、両社の対応スピード感等に大きな差が感じました。LINE には7月12日に脆弱性報告し、2週間後に修正され、一ヶ月後に賞金を講座に振り込まれました。Yahoo はバグバウンティプログラムが存在しないので、8月5日にIPA経由で報告したんですが、一通目の返信は報告してからおおよそ三週間後でした。11月12日に Android 版 SDK の work around がリリーされ、12月19日にやっと PKCE がリリースされました。ちなみに、11月18日に LINE とヤフーが経営統合され、ヤフーのセキュリティ事情も LINE と統一されたら嬉しいですよね。そして先日 YJTC でこのような発表安全・安心に向けたYahoo! ID連携の改善とネイティブアプリのID連携の実装があり、スライドを読んだら「なるほど PKCE はなかっただけでなく、PPID も対応してなかったですね」と思いました。LINE の場合は PKCE はあったし、PPID もずっと前から対応してた気がします。まあある意味では両社のセキュリティレベルも統一されつつあると言えるでしょうかね。めでたし。
(完)
NULL