3 ポイント 投稿者 GN⁺ 2024-03-19 | 1件のコメント | WhatsAppで共有
  • 誤って設定されたFirebase セキュリティルール1つが、数百のサイトにおけるユーザーデータの露出につながり、確認されただけで約1億2,460万件のレコードに達した
  • 調査は、Webサイトと読み込まれたJavaScriptバンドルからFirebase設定変数を探す方法で始まり、Pythonスキャナーのメモリ問題によりGoで書き直された
  • 補助スキャナーCatalystは、Firebaseコレクションが読み取り可能かどうかを自動確認し、サンプルデータをもとに露出した情報の種類と規模を推定する
  • 集計された露出項目には、名前84,221,169件、メールアドレス106,266,766件、電話番号33,559,863件、平文パスワード20,185,831件、決済情報27,487,924件が含まれる
  • 研究者らは13日間で842件の通報メールを送ったが、設定を修正したサイト所有者は24%、返信した割合は1%、バグバウンティを提案したのは2サイトにとどまった

インターネット規模のFirebase露出スキャン

  • Chattr.aiの侵害事例 の後、誤って設定されたFirebaseインスタンスを通じて露出したPIIを探すためのインターネット全体スキャンが始まった
  • 最初のPythonスキャナーは、Webサイトや読み込まれた.jsバンドルからFirebase設定変数を確認していたが、約500スレッドで動作する中でメモリ使用量が増え、1時間以内にOOMが発生した
  • その後Goで書き直されたスキャナーは550万ドメインを対象に実行され、当初予想の約11日より長い2〜3週間を要した
  • 初期の手作業レビューだけでも136サイトと620万レコードを見つけたが、候補リストが膨大になったため完全自動化が必要になった

Catalystと露出規模の算定

  • Catalystは候補サイトやJavaScriptバンドルを入力として受け取り、一般的なFirebaseコレクションと、JavaScript内で直接言及されたコレクションの読み取りアクセス可否を自動確認する
  • 読み取り可能なコレクションを見つけると、100件のレコードサンプルを収集して含まれる情報の種類を確認し、それをコレクション全体のサイズに掛けて影響を推定する
  • 結果の保存先には、PostgreSQLベースのオープンソースFirebase競合製品であるSupabase が選ばれ、整理されたデータは非公開データベーステーブルにアップロードされた
  • 集計値は次のとおりで、実際の露出規模は表示された数値より大きい可能性が残っている
    • 全レコード: 124,605,664件
    • 名前: 84,221,169件
    • メールアドレス: 106,266,766件
    • 電話番号: 33,559,863件
    • パスワード: 20,185,831件
    • 決済情報: 銀行情報、請求書など27,487,924件

影響が大きかったサイト

  • Silid LMS

    • 学生と教師向けの学習管理システム
    • 名前、メールアドレス、電話番号を含む2,700万人分のユーザーレコードが露出し、最大規模となった
  • オンライン賭博ネットワーク

    • 相互にリスキンされた9つのサイトで構成される
    • 一部のスピンは勝率が0%になるよう操作されていた
    • 銀行口座の詳細なログイン情報が800万件と最も多く露出した
    • 平文パスワードも1,000万件で、影響を受けたサイトの中で最大規模だった
    • 問題を通報しようとする過程で、カスタマーサポートが会話中に言い寄ってきた
  • Lead Carrot

    • コールドコール用のオンラインリード生成サービス
    • 露出したユーザー情報の規模は上位3位で、2,200万人に影響がある
  • MyChefTool

    • レストラン向けのビジネス管理アプリおよびPOSアプリケーション
    • 露出した名前の数は1位、メールアドレスの数は2位で、それぞれ1,400万件1,300万件が露出した

通報後の反応

  • 研究者らは13日間で842件のメールを送信した
    • 85%は配信され、9%は返送された
    • サイト所有者の24%が誤設定を修正した
    • 返信したサイト所有者は1%にとどまった
    • 0.2%にあたる2つのサイト所有者がバグバウンティを提案した

1件のコメント

 
GN⁺ 2024-03-19
Hacker News の意見
  • Firebase で長く働いていたが、セキュリティルールの問題は製品をずっと悩ませてきた
    自動で期限切れになるデフォルトルール、教育の強化など、さまざまなアプローチを試したが、結局いまだに安全でないデータベースが数多く見える
    理由は複雑だが、Firebase 式のセキュリティルールはまだ馴染みの薄い概念で、既存の場所にデータを追加する新しい開発者が、そのデータのプライバシー要件の変化に合わせてルールまで直さないことが多い
    また、それぞれが作ったバックエンドがもたらしていた「曖昧さによるセキュリティ」がなくなり、大規模スキャンが容易になった
    特に Realtime Database のルールは書きにくく、スケーラビリティも良くないが、自動スキャンは通常、開かれたデータしか探さないので、read write true より少しマシなだけでも防げていた
    技術的に Firebase のアプローチ自体が間違っているわけではないが、保存データとセキュリティルール中心のモデルを使うほぼ唯一のバックエンドなので、誤解や誤用、こうした事故にさらされやすい

    • 正直、フロントエンドがデータベースに直接データを書き込めるモデルは、セキュリティルールがあっても常に疑わしく思っていた
      バックエンドでは検証・セキュリティルールが仕様の一部に見えるが、Firebase のセキュリティルールは別プロセスなので忘れられやすく、新機能を作るたびに再評価しなければならない
    • Google のサポートチャネルに連絡して、支援するかウェブサイト側に問題を知らせられるようにしてほしいと頼んだが、望むなら代わりに機能リクエストを作れるという返事しか得られなかった
      プロジェクト所有者に通知できる人の注意を引くには、Firebase 内部でかなり高い段階までエスカレーションする必要があったのだと思う
    • https://firebase.google.com/docs/rules/basicsを見ると、あらかじめ決められたセキュリティルールテンプレートだけを選ぶ簡易セキュリティモードが実用的なのか気になる
      たとえば記事の「コンテンツ所有者のみアクセス」や「属性ベース・ロールベースアクセス」のようなテンプレートで、ほとんどのアプリのパターンをカバーできるのか、それとも本当にカスタムルールが多く必要なのか疑問だ
      セキュリティルール作成の大きな問題は、ほぼすべてのミスがセキュリティ問題になるため、必要なければ触りたくないという点にある
      ルールが厳しすぎるとアプリが動かないので直ちに分かるが、開きすぎている場合は過剰なアクセスを実際に試すまで表面化しにくい
      関連して、各セキュリティルールごとにアクセス拒否の例示テストケースを開発者に書かせる方式も検討に値する
    • 私たちには簡単なコツが大いに役立った: fireplan というルールトランスパイラがすべてのプロパティにデフォルトの "$other": {".read": false, ".write": false} ルールを追加する
      おかげで新しいフィールドは明示的に追加する必要があり、新しい値が既存ルールを知らないうちに「継承」することがほぼ不可能になった
      Firebase を10年以上使ってきたので、最新のルールツールもこうしているのかは分からない
      本当に役立つのは、制御しにくい複数のクライアントバージョンがある状況で、フィールド名変更やデータ構造変更を標準で支援すること、データベースを起動しなくてもルールを軽量にテストする方法、本番環境でルール失敗時により良いデバッグ情報を出すことだ
      失敗するたびにルールがアクセスしたすべての値も一緒に記録しなければ、変化するデータによって生じる一時的な失敗をデバッグできない
    • Firebase と Firestore をかなり擁護してきたが、上の内容にはすべて同意する
      これは十分に説明されていない概念モデル
      プロジェクトでは各コレクションに、公開、ユーザーデータ、認証ユーザーのみ公開、管理者専用のようなセキュリティプロファイルがあるべきだと言い、コレクションごとにカスタム条件を書くのではなく、セキュリティルール関数でこうしたカテゴリを強制する形で取り組んでいる
      フィールド単位ではなくコレクション単位でセキュリティを考えれば、1つのドキュメント内に異なるセキュリティ意図が混ざることを減らせる
      コレクションが公開なら、公開でないフィールドを含めるべきではなく、必要なら Firestore トリガーでセンシティブなコンテキストから公開コンテキストへデータを複製できるが、逆方向はできない
      問題は、ルール自体の外側でルールの意図を文書化しなければならないため誤適用しやすい点で、以前はテストを書くのも苦痛だったが、今はかなり改善されている
  • “How I pwned half of America’s fast food chains, simultaneously.”を思い出す: https://mrbruh.com/chattr/
    HN: https://news.ycombinator.com/item?id=38933999

    • どちらの記事も私が書いたもので、今回の記事はそのブログ記事の続編
    • 正常だ。そのブログ記事の6番目の単語がその記事へのリンクになっている
      After the initial buzz of [pwning Chattr.ai] had settled down, […]
  • 私の見間違いでなければ、記事末尾の時点で、こうした脆弱性のあるサイトの**75%**がまだそのまま開いていて、ダンプ可能な状態という意味ではないのか?
    とんでもないことだ
    ある日には、コンピュータを触るには免許が必要だと思うこともある

    • 多くの会社には常勤の開発者がいない
      ウェブサイトを作ってくれる制作会社に外注し、その制作会社は開発者を入れ替え続け、最初は優秀な開発者を付けるが、その後は会社が不満を言わない限り、より経験の浅い開発者に契約を任せる、という具合だ
      脆弱性のメールはスパムとして無視されたか、転送された後に放置されたか、PM の会議予定キューに入り、クライアントにできるだけ請求しながら修正する項目になった可能性が高い
      専門免許が義務の分野にも、無能な免許保持者は多い
      医師も教育と免許要件は非常に厳しいが、ヤブ医者や免許を持つ代替医療従事者には事欠かない
    • 悲しいが事実で、おそらく実際にはずっと多いだろう
      各サイトに、影響を受けた内容、修正方法、連絡方法を盛り込んだカスタムメールを送り、最善を尽くした
    • その通り。だから悪意ある行為者がすぐ悪用できないよう、影響を受けたサイト一覧は公開できなかった
    • 個人情報流出で会社が潰れない限り、彼らにとっては事業コストであり、そのコストはユーザーに転嫁される
  • これはPMの cheap-fast-good の三角形で安くて速い選択をした必然的な結果だと思う
    残念ながら、一部の顧客やユーザーの懸念は議論から外され、彼らの個人情報がコストになった
    ここに挙がっている企業のうち、そうした判断をしてもリーダーシップが変わっていないところには注意すると思う
    多くの企業が顧客を守るほど十分に気を配っていないことは何度も証明されており、歴史は繰り返す

    • おおむね同意だが、ごく少数ながら、感謝しつつ素早く修正した良い事例もあった
  • Firebaseについてごく基本的な質問がある:この記事のアプリの大半は、カスタムのサーバーコードなしで、静的ホスティングされたクライアント側JavaScriptだけで実装されていたのか?
    バックエンドは100% GoogleがホスティングするFirebase設定という意味なのか気になる
    もしそうなら、数百万人のユーザーがいるサイトでそのようなアーキテクチャがここまで一般的になっていたとは知らなかった

    • その通り。完全にクライアント側か、サーバーを経由していても素朴に通している方式だ
      APIでデフォルト許可のセキュリティモデルを置くと、必然的にこうなる
      残念ながら、JavaScript開発者向けのライブラリには安全でないデフォルト値がよくあり、GraphQLもこうした問題が出そうな領域に見える
    • 混在している可能性もある
      Firebaseにはクラウドから呼び出せる関数であるFirebase Functionsもあり、そのコードは公開されない
      ただしFirestoreやFirebase Realtime Databaseはいずれもユーザーがセキュリティルールを設定する必要があり、そうしなければ誰でも全データを読める
    • かなり過激な構成に見えるが、バックエンドのSQLスキーマに適切な認可ルールをコーディングすれば動かせる
      バックエンドで適切な認可ルールを簡単に書けるようにすることが重要だ
  • こういうのを見ると、ずいぶん前にパスワードマネージャーとバーチャルカードを選んでおいてよかったと感じる
    それでもインターネットはさらに怖くなっている
    ほとんどの人は、Webがどれほど脆弱で、自分たちがどれほど露出しているかをまったく知らない

    • 今後さらに悪化しそうだ
      AIエージェントがボットよりはるかに効率よく脆弱性を見つけるようになるだろうから、奇妙な未来が待っている感じがする
    • 時間が経つほど、サービスはWebサイト作成を簡単にし、より多くを抽象化するので、開発者は何を設定すべきか分からなくなる
    • パスワードマネージャーだけでは足りない
      登録するサービスごとに固有のメールアドレスを使うべきだ
      事故が起きたときに被害を限定でき、他のサービスと照合されて公開情報収集の対象になるのも防げる
      ときどきその固有アドレス宛に悪意あるメールが来れば、サイト運営者より先に侵害に気づけることもある
  • 「スレッドが約500個あるPythonプログラムは、時間が経つにつれてメモリを食い始める」という部分について、もっと知っている人はいる?
    自分もPythonでスレッド数百個のスクレイパーを持っているが、かなりメモリを食っている気がする
    回避策があるのか、それとも別の言語で書き直すのが唯一の解決策なのか気になる

    • Pythonでもできるが、Pythonの参照カウントがスレッドとどう相互作用するのかを掘り下げる必要がある
      個人的にはスレッドよりプロセスを好み、共有メモリよりワーカープールとメッセージバスを使う
      この解決策にも欠点と多少のオーバーヘッドはあるが、メモリ問題をずっと気にしなくて済む
      クローラーはプロセス数が比較的一定で、各プロセスの作業が独立しているため、プロセスモデルのほうが合っているように見える
    • import multiprocessing as threading
    • 正確な問題は分からないが、正直Pythonはこうした作業に向いた言語ではない
      書き直すのが、実質的にほぼ唯一の解決策だ
    • この用途にはasyncioを使うのが正解だ
      まさに非常によく合うユースケースだ
  • よくやった
    影響を受けたユーザー数が実際にはもっと多い可能性が高い、という結論にどうやって至ったのか気になる
    見たところ、ギャンブルサイトやLead Carrotのような一部サイトには偽のアカウントデータがかなり混ざっていた可能性もありそうだ

    • 複数のサイトを手動で確認してみると、自動スキャナーは変数名から電話番号のような既知のデータ種別を確認する方式なので、英語以外の個人情報をうまく識別できていなかった
      英語サイトでしかうまく機能しない方式だ
    • ギャンブルサイトのデータが偽物ではないことは確認したが、Lead側は分からない
      もっと多いと言った理由は、スキャン一覧になかった他のサービスも脆弱である可能性があるためだ