スウェーデンの BankID は、インターネット プロバイダー、オンライン バンキング サービス、賭博 Web サイト、特に政府の Web サイトなど、複数のサービスへの認証に、スウェーデンの居住者のほとんど、あるいは全員が使用するデジタル ID 形式です。
私自身はスウェーデンに住んでいて、頭の中では常にハッカー精神が渦巻いているので、セキュリティ研究を行うのは非常に興味深い分野になるだろうと判断しました。
この投稿では、BankID の認証プロトコルの安全でない実装が原因で、ほとんどのスウェーデンのサービス プロバイダーに存在することがわかった新しい脆弱性について説明します。
ここでは、このようなプロトコルがどのように機能するか、脆弱な構成はどのようなものか、それをどのように悪用するか、どのように修復するか、そして最後に、これらの種類の攻撃が eID の全体的な実装にどのような意味を持つかについて簡単に説明します。
BankID は、ユーザーのデバイスにインストールされるサービスで、スウェーデンのpersunnumer (個人番号) を持っている場合に、スウェーデンの銀行にリクエストすることで取得できます。アプリケーションはユーザーのデバイスにインストールされ、その個人番号に接続され、基本的にそのユーザーの ID をそのようなアプリケーションに結び付けます。電子 ID システムは、多くの場合、このように機能します。つまり、政府公認の信頼できる第三者が、特定の個人に結び付けられたソフトウェアを配布し、サービスがそのソフトウェアのプロバイダーと統合されて、ユーザーがそのプラットフォームで認証できるようにします。これは、サービスが人々を簡単に認証できるようにする共有信頼モデルです。
BankID も例外ではなく、このようなサービス (今後は Relying Party (RP) と呼ばれる) に関するドキュメントを提供しており、認証フローを BankID と簡単に統合できます。https ://www.bankid.com/en/utvecklare/guider/teknisk-integrationsguide/rp-introduktion 。
BankID では、ユーザーを認証するために 2 つの主なフローが使用されます。
同じデバイスで認証する
別のデバイスで認証する
これら 2 つについては後ほど再度取り上げますが、どちらのフローも、RP が BankID の API にリクエストを送信して認証オーダーを開始することから始まります。この POST リクエストでは、RP はendUserIp
パラメータを指定する必要があります。このパラメータには、ログインしようとしているユーザーの IP が含まれています。これは、レポートの後半で重要になります。
/auth
APIエンドポイントは次のような応答を返します。
HTTP/1.1 200 OK Content-Type: application/json { "orderRef":"131daac9-16c6-4618-beb0-365768f37288", "autoStartToken":"7c40b5c9-fa74-49cf-b98c-bfe651f9a7c6", "qrStartToken":"67df3917-fa0d-44e5-b327-edcc928297f8", "qrStartSecret":"d28db9a7-4cde-429e-a983-359be676944c" }
orderRef
、RPが/collect
エンドポイントに対して認証ステータスを確認し、後でその人から必要なユーザー情報を取得するために使用できる識別子です。autoStartToken
は、クリックすると BankID アプリが開き、ユーザーに認証を求めるディープリンクを作成するために RP が使用するトークンです (これは非常に重要です) qrStartToken
とqrStartSecret
は以下で説明しますが、実行されるセキュリティ研究にとって厳密には重要ではありません。
RP は、ユーザーの IP に加えて、BankID アプリケーションに表示されるテキストや認証要件など、認証順序のその他のパラメータを指定できます。
認証要件の中で、この投稿で焦点を当てるのは証明書ポリシーと呼ばれるもので、これにより RP は BankID に、ユーザーが 2 つのフローのどちらを選択したかを伝達できるようになります。
ユーザーが同じデバイスで BankID を使用して認証されることを選択した場合、RP はautoStartToken
を使用して、 bankid:///?autostarttoken=7c40b5c9-fa74-49cf-b98c-bfe651f9a7c6&redirect=https://service.com/login
のようなディープリンクを作成します。このディープリンクはユーザーの OS によって取得され、BankID アプリケーションに渡されます。
このフローを調査しているときに、BankID 側からのredirect
パラメータの検証が行われていないため、オープン リダイレクトの脆弱性が見つかりました。この追加のバグによってセッション ハイジャック攻撃がさらに強力になる理由については、後ほど説明します。
ユーザーが別のデバイスで BankID を使用して認証されることを選択した場合、RP はqrStartToken
とqrStartSecret
を使用して、(前述の/collect
エンドポイントから次のフレームのデータを取得することによって) 動的な QR コードを生成します。この QR コードは、ユーザーが Mobile BankID アプリケーションを使用してスキャンできます。
これらは、認証命令を開始するときに RP によって指定される必要があります。これにより、フィッシングを軽減するために、フローが一致しない場合に BankID が認証の試行を拒否できるようになります。たとえば、ユーザーが「同じデバイスでの認証」を選択した場合、RP はそれを BankID に伝え、モバイル BankID で認証が試行されたり、QR コードが使用されたりした場合に、アプリケーションがそれを拒否できるようにする必要があります。
これらに加えて、認証が完了すると、RP は/collect
API エンドポイントから BankID のアプリケーションを開くために使用されたipAddress
を取得できます。ユーザーが「同じデバイスでの認証」を選択した場合は、これを RP 上のユーザーの IP アドレスと照合する必要があります。
認証フローが改ざんされないようにするために、証明書ポリシーとipAddress
を使用する必要があります。
しかしながら、これらのセキュリティ対策が実施されているにもかかわらず、BankID はそれらの重要性を概説しておらず、提供されている実装例でも正しく実装されていません。https ://github.com/BankID/SampleCode
では、このプロトコルが安全に実装されていない場合はどうなるでしょうか?
私が最初にbankid:///
ディープリンクを見たのは、BankID でログインしてアクセスできる大学の願書を閲覧していたときでした。最初、このディープリンクを誰かに送信したらどうなるのだろうと考えました。そこで、友人に送信したところ、友人がクリックしたのですが、驚いたことに、友人が BankID を開くと、彼の大学の願書がすべて目の前に表示されていました。
そのとき、私は BankID の API を調べ始め、独自の RP を実装し、今説明したすべてのことを学びました。
数週間の研究の後、私は 30 を超える RP のbankid:///
ディープ リンクの取得を自動化するスクリプトを開発しました。このスクリプトは Web サーバーを起動して各サービスのパスを作成し、ユーザーが特定のサービスのリンクにアクセスすると、スクリプトは新しいリンクを取得してユーザーをそのリンクにリダイレクトします。これにより、ユーザーのデバイスで BankID アプリが開き、認証時にユーザーの代わりに私が認証されます。
私がこれを実現できたのは以下の理由からです:
RPは証明書ポリシーをBankIDに送信しなかったため、ディープリンクを取得してモバイルBankIDアプリに中継することができました。
RPはリンクを要求したIPアドレスと認証を完了したIPアドレスを比較しなかった
「別のデバイスで認証」オプションが選択されている場合でも、RPはリンクを提供しました
これにより、セッション固定の脆弱性が発生しました。
AmazingSevice AB という脆弱なサービスを想像してみましょう。このサービスは、提供されたサンプル コードに従って BankID フローを実装し、その実装をhttps://amazingservice.se/login/bankid
でホストしています。
脅威アクターは AmazingSevice AB に保存されているユーザー データに興味があり、被害者を狙っています。彼はbankid:///
リンクの取得を自動化し、それを自分のサーバーでホストし、悪意のあるサーバーへのリンクを被害者に送信するだけです。フィッシングの配信方法 (SMS、電子メールなど) を選択した後、AmazingSevice AB を装ったメッセージにリンクを埋め込み、被害者にログインを要求します。
このようなアカウント乗っ取りにはソーシャル エンジニアリングがほとんど関与していません。被害者がリンクをクリックすると、すぐに BankID を開くように促され、攻撃者のサイトの「未知の領域」を離れ、より馴染みのあるインターフェースである BankID が表示されるからです。さらに、被害者が BankID アプリケーションで目にする認証要求は AmazingSevice AB によって要求されるため、不正行為を検出することは不可能です。
被害者が認証すると、攻撃者のセッションが被害者のアカウントに認証されます。被害者は、BankID に存在するオープン リダイレクトの脆弱性を悪用してさらに騙され、攻撃者がredirect
パラメータをhttps://amazingservice.se/login/bankid
として指定できるようになります。これにより、被害者は正当なサービス Web サイトにリダイレクトされ、認証が成功しなかったと単純に考えてしまいます。
明らかな理由により、私が報告した会社の 1 つを使用できなかったため、代わりに、デモでは BankID のデモ サービスがこれに脆弱であることを示しています。
右隅には、リンクを受け取った被害者の視点が示されています。ここでは、攻撃者の Web サイトにアクセスしてシミュレートしています。被害者がリンクにアクセスすると、攻撃者のサーバーはヘッドレス ブラウザーを開き、 bankid:///
リンクを抽出して被害者の電話に中継します。BankID のアプリには、「Test av BankID」と表示されています。これは、BankID のデモ サイトの正当な発信元です。さらに、ビデオの冒頭では、認証中に IP アドレスのチェックが行われていないことを確認するために、VPN がオンになっています。最後に、攻撃者のラップトップで、攻撃者が被害者 (Johan Johansson) としてログインしていることがわかります。
セッション固定バグは、スウェーデンの BankID を認証プロバイダーとして使用し、証明書ポリシーとipAddress
チェックを誤って (またはまったく) 実装しているアプリケーションで、 1 クリックのアカウント乗っ取りにつながります。これは非常に深刻な問題です。なぜなら、ユーザー認証に BankID を使用しているサービスは、非常に機密性の高いデータやアクションにアクセスできることが多いからです。30を超えるアプリケーションがこの攻撃に対して脆弱であることが判明し、可能な限り多くのアプリケーションに連絡した結果、主要なプラットフォーム全体で 11 件のバグ報奨金レポートが承認されました。
この脆弱性を報告したサービスの 1 つが、この問題が広範囲かつ深刻であるため、スウェーデンの国家 CSIRT と連絡を取ることができました。話し合いは始まったばかりなので、最新情報を知りたい場合は、Twitter で私をフォローしてください (X) @m4st3rspl1nt3r
安全な BankID RP API 実装の例を探している場合は、Golang ライブラリとして使用したり、カスタマイズしてマイクロサービスとしてデプロイしたりできる例を作成しました。こちらから参照できます。
影響を受けたサービスのほとんど、特に BBP と VDP を持つサービスは、私の報告に対して非常に受容的で迅速に対応してくれました。しかし、BankID の対応は少し異なっていました。さまざまなチャネルを通じて何度も連絡を取った後に受け取った 1 通のメールでは、問題を認識しているが、RP の「統合の容易さ」を維持するためにできることはあまりないと説明されていました。残念ながら、RP 側で変更を加える必要のある計画された緩和策は、次のように私に伝えられました (しかし、何らかの理由で、ドキュメントのどこにも記載されていません)。
RP が設定できる追加の要件はリスクです。これは、トランザクションの許容リスク レベルを設定します。トランザクションのリスクが必要な制限よりも高い場合、トランザクションはブロックされます。「LOW」 - 低リスクの注文のみを受け入れます。「MODERATE」 - 低リスクと中リスクの注文を受け入れます。これが設定されている場合、RP によって IP チェックが提供された場合、当社側で IP チェックを実行します。提供された場合、リスク監視されるその他のリスク パラメーターは、referringDomain、userAgent、および deviceIdentifier です。
さらに、オープン リダイレクトの脆弱性を修正する計画も実施されています。
これに関する私の個人的な意見は、非常に機密性の高いユーザー情報を保護するために使用されることが多い、非常に重要で広く採用されている認証プロバイダーを開発および運用する場合、RP が安全に統合できるようにセキュリティ メカニズムを適切に文書化する必要があるということです。オプションのセキュリティ機能はまったく役に立ちません。開発者が特定の機能/パラメーターを実装しないことで時間を節約できるのであれば、そうなるでしょうし、RP 側を責めることはできません。BankID は、できるだけ多くの不正防止機能とセキュリティ機能を自社側に移行して「統合の容易さ」を維持するように最善を尽くすべきですが、RP が実装する必要がある追加のセキュリティ機能も適切に文書化する必要があります。必須であり、オプションではないことに注意してください。
このブログのこの部分は純粋に私の意見です。
私にとって、この脆弱性は、国の国民にとって極めて重要なシステムを民間企業に完全に管理させることの危険性を示す例です。これが単なるソフトウェア会社の脆弱性よりも深刻であると考える理由は、BankID が850 万人以上のスウェーデン居住者によって使用されているものであり、銀行、保険会社、電力会社、および現実世界に影響を与えるその他の機密プラットフォームにログインするために使用されているからです。
誰かが Facebook でアカウント乗っ取りを発見した場合、写真がいくつか失われる可能性があります。また、誰かがあなたの国の eID プロバイダー (多くの場合、民間) に脆弱性を発見した場合、誰かの人生に想像を絶する影響が生じる可能性があります。
ますます多くのヨーロッパ諸国が eID を採用しており、EU は今後数年間で独自の EU eID を導入する予定です (詳細については、こちらをご覧ください)。
私の希望は、規制当局が eID プロバイダーが公的機関によって完全に開発および管理されるように推進し、そのようなシステムがオープンソースであり、セキュリティ上の欠陥がないか定期的に監査されることを義務付けることです。
このような重要なソフトウェアが民間企業によって開発されている場合、どうすればそれを社会で安全に受け入れることができるのでしょうか?
このブログ投稿の主なトピックは BankID に対するセッション固定攻撃でしたが、他の多くの認証/識別プロバイダーもすべて同じ欠陥を抱えて設計されていることがわかりました。認証フローを完了するために別のデバイス (多くの場合、携帯電話) の使用を必要とするプロバイダーに、新しい脆弱性クラスが見つかります。
研究は継続中で、近いうちにさらなる発見と、このような脆弱性を自動化して悪用するために開発中のツールを公開する予定です。次回のトピック「設計によるセッション固定 - クロスデバイス認証の悪夢」をお楽しみに。
それまでは、惑星をハックしましょう!