Skip to main content

セキュリティの恐怖体験:個人情報を誤って漏えい

blog feature security alert purple

2021年10月25日

0 分で読めます

怖い話に勝るものはありません……特にソフトウェア開発やセキュリティの話ならなおさらです。ソフトウェアを開発していて、いったい何が起こり得るでしょうか???もっと言えば、資金調達がまだ決まっていない小規模な研究開発プロジェクトで、チームと一緒に作業しているとき、何が起こり得るでしょうか……

次の期間の資金を確保するため、ものすごいプレッシャーの中で機能を急いで提供する状況が、いつ災害が起きてもおかしくない土壌になることは想像できるでしょう。特に、プロジェクトの最終目標が明確でなく、アイデアが日ごとに変わる場合はなおさらです。

ここからは、セキュリティの観点で何がうまくいかなかったのか、私の体験をお話しします。この小規模な研究開発プロジェクトは、銀行や保険会社のような大きな組織の一部だったため、単なる小さなプロジェクト以上のものが懸かっていました。

プロジェクト

プロジェクトは、建物や住宅などの不動産を調べるモバイルアプリとして始まりました。システムのロジックの大部分はサーバー側にあったため、Javaで優れた(マイクロ)サービス指向のソリューションを構築しました。

サービスの1つがプロフィールサーバーでした。各プロフィールにはランダムに生成されたUUIDと、設定のリストが含まれていました。主要機能の1つは、ユーザーが匿名でアプリを利用できることです。そのため、UUIDをデバイスのローカルストレージに保存し、それを使ってサーバーからプロフィールを取得していました。簡単に言えば、サービスは次のようなものでした。

UUIDを使ったプロフィール作成、設定更新、プロフィール取得のリクエストが、Profile Serviceを経由してプロフィールデータにルーティングされる様子を示す図。

あるとき、ユーザーがシステム内の不動産を自分のものとして登録できるようにする、というアイデアが出ました。これは主に、ユーザーがその家や建物を所有している場合を想定しています。所有者は、不動産に写真や説明を追加できるようになりました。不動産を登録できるユーザーは1人だけです。

この新機能により、今回の話に関わる重要な変更が2つ生じました。

  • ユーザーが住宅を登録できるように、「MyHouse」という新しいサービスを作成しました

  • プロフィールサービスも拡張する必要がありました。ユーザーがログインして住宅を登録できるようにするため、既存のプロフィールサービスに登録機能を追加しました。

サービスは次のような構成でした。MyHouseオブジェクトが、UUIDを含むユーザープロフィールに紐付いており、プロフィールにはメールアドレスも含められるようになりました。

ProfileサービスとMyHouseサービス、および入力、出力、関連するプロフィール、メールアドレス、設定、住所、画像データを示す図。

重要なのは、これまでと同様に匿名での利用も引き続きサポートするよう指示されており、この機能は既存の機能に追加する形で実装する必要があったことです。

問題点

新しいMyHouseサービスには、登録された不動産をすべて一覧表示するエンドポイントがありました。そこでは、プロフィールのUUIDを含むMyHouseオブジェクト全体がJSONで公開されていました。以前の機能をサポートする必要があったため、プロフィールのUUIDさえ分かれば、引き続きプロフィールを検索できる状態でした。

ProfileサービスとMyHouseサービスを示す図。プロフィールと住宅に関するリクエストが、UUIDベースのデータフィールドに対応付けられています。

要するに、モバイルのフロントエンドではUUIDはまったく必要ありませんでした。しかし、通常のHTTPリクエストを送り、MyHouseオブジェクトを取得できれば、2回目のリクエストでUUIDを使ってプロフィールを検索できてしまいます。こうして、不動産の実住所とメールアドレスを紐付けられるようになりました。メールアドレスの多くはfirstname.lastname@provider.com(またはそれに類する形式)なので、個人と実住所を結び付けられるデータ漏えいが発生したのです。しまった、これは個人を特定できる情報、つまりPIIの漏えいでした。

修正とその後

この件は、会社のセキュリティ部門に匿名で報告されました。幸いにも、倫理観のある人が責任ある開示を行ってくれました。問題を把握した後、修正は本番環境への反映を含めても5分で完了しました。MyHouseのPOJOのUUIDフィールドに@JsonIgnoreアノテーションを追加してJSONへのシリアライズを防ぎ、プロフィールと実住所を紐付けられないようにしました。

エンジニアリングの観点からは、ここでこの記事を終えてもよいでしょう。しかし、修正自体は簡単でも、その後の対応は非常に大きな負担になります。まず、インシデントについて次々と質問が寄せられました。

  • 誰の情報が漏えいしたのか?

  • どのくらいの期間、漏えいしていたのか?

  • このデータ漏えいの影響は何か?

  • どのようなデータが漏えいしたのか?

  • この漏えいの被害者は誰か?

  • なぜ防げなかったのか?

  • などなど、尽きることがありません。

こうした質問への対応として、私とチームは膨大な書類を作成しなければなりませんでした。答えが明らかなものもありましたが、プレッシャーの大きい研究開発プロジェクトだったため、適切なログ記録をまだ導入していませんでした。被害者を特定することは不可能でした。悪意ある人物に悪用されたかどうかさえ分かりません。何も分からなかったのです。

最悪だったのは、上層部から「エンジニアにセキュリティ意識がまったくないとは残念だ」や「このチームは無能だ。気づくべきだった」といった言葉で責められたことです。膨大な書類対応に加えて、開発やセキュリティの知識がないマネージャーが、あらゆることに細かく口を出すようになりました。

学んだこと

まず、あらゆるものをログに記録するようにしました。セキュリティ問題への対処も大変ですが、その後の対応や質問はまったく別の難しさがあります。次に、データモデルをよく確認し、フロントエンドで必要のないデータをRESTエンドポイントで公開していないかを調べました。

エンジニアリングチームはこのインシデントを機に、プロダクトマネージャーからの過度な要求やプレッシャーに異議を唱えました。しかし、セキュリティ意識とは開発プロセスにセキュリティを取り入れることであり、人を責めることではありません。率直に言って、適切な解決策は、開発プロセスに役立つ文化とツールに投資することだったはずです。その後まもなく、私はこの会社を離れることにしました……

今回のようなセキュリティの恐怖体験をもっと知りたい方は、ぜひTwitter(@snyksec)をフォローしてください! #31DaysOfSecurity