継続的なセキュリティ対策をするために脅威分析をしました

この記事では、PLAIDKARTEというシステムの脅威分析をした話について書いています。

脅威分析とは、アプリケーションやシステムなどが直面する可能性のあるすべての脅威を明らかにして、その脅威のリスクを相対的に把握するために行うことを言います。
脅威とはリスクを発生させる要因のことで、クロスサイトスクリプティングなどの脆弱性を思い浮かべるとわかりやすいです。

たとえば、STRIDEと呼ばれる脅威モデリングの手法では、6種類の脅威をカテゴライズしています。

  • Spoofing(なりすまし) - 第三者が別のユーザーになりすます
  • Tampering(改ざん) - データを改ざんする
  • Repudiation(否認) - ログの消去により証拠隠滅を図る
  • Information disclosure(情報の漏洩) - 個人情報などが流出する
  • Denial of service(DoS攻撃) - サービスに負荷をかける
  • Elevation of privileg(権限昇格) - 管理者権限を持っていないユーザーが管理者権限の操作ができるようになる

このような脅威がシステム上にあると仮定して、それが発生したときのリスクがどれぐらいあるのか、それへの対策ができているのかなどを考えるリスク分析のことを言います。

なぜ脅威分析をしたのか

セキュリティ対策においてリスクがなくなることはありません。
一方でセキュリティの問題に対応していくリソースは無限でないため、どこからやるべきなどの優先順位をつけることが重要です。
この優先順位をつけるために、どこにどの程度のリスクが存在するのかを相対的に把握必要がありました。

また、実装の問題を見てしまうと目の前の問題に時間を使いすぎて、本当に大切な部分への対策ができなくなっていないかという懸念もありました。
セキュリティの対策にはある程度の網羅性が必要であるため、その部分も考えていく必要がありました。

この対応するべき優先順位の決定と網羅性をカバーするために、KARTEのシステムの脅威分析してみようと話になりました。

ここで重要なのは、脅威分析したからといって勝手にシステムが安全になるわけではないということです。
その分析をしていく中でそれぞれの脅威のリスクが高いのか低いのかを判断して、実際に対策していくことが重要です。

そのため、脅威分析はセキュリティ設計のサイクルの一部分という認識です。
リスクを分析し、リスクが高い問題はIssue化し、実際にそれをFix/対策する。
そして、再度リスクの分析をしていくというサイクルの一部分を構成するものとして脅威分析があります。

セキュリティ設計のサイクル

脅威分析は直面する可能性がある脅威を明らかにするという網羅性を求める作業でもあります。
そのため、今回のKARTEのシステムの脅威分析では、EGセキュアソリューションズ株式会社さんにご協力いただき、客観的な外部の目を入れることでより網羅的な脅威分析を実施しています。


ここからは実際にどのような流れで脅威分析していったかを記録形式で書いていきます。

脅威分析を始める前に

脅威分析にはフレームワークと言えるようないくつかの手法があります。
しかし、システムやアプリケーションによって脅威分析のやり方は異なります。
なぜなら、システムによって守りたいものが異なったり、構造が異なるためです。

たとえば、IPAが公開している制御システムのセキュリティリスク分析ガイド 第2版ではIoTデバイスについて書かれています。
IoTデバイスについてのリスク分析するには、IoTデバイスを設置する施設のセキュリティなどの物理的なアクセスについても考慮する必要が出てきます。
しかし、GCPやAWSなどのクラウドサービスを使う場合には、サービス開発者が施設の物理アクセスについてまで考慮する必要性は薄いでしょう。
AWSなどのクラウド事業者は、情報セキュリティに関して一般に責任共有モデルを採用していています。

このように、脅威分析のやり方は扱うものや作るサービスによって異なります。
そのため、KARTEに適した脅威分析を模索することからまず始まりました。

先ほども書いたように脅威分析にはいくつかのフレームワークがあるため、そのテンプレートを使って始めることがスタートしました。
EGセキュアソリューションズさんに脅威分析で利用できるテンプレートを用意してもらって、それをKARTEに当てはめて考えて見るという形です。

KARTEの基本的なデータフロー

今回の脅威分析はKARTEの基本的な使い方を対象にして開始しました。
KARTEはさまざまな使い方ができるため、まずは基本的な使い方(基本的なデータフロー)に絞って分析し、そのあとに別のシステムや使い方に横展開していくことにしました。
この脅威分析では、この基本的な使い方を"Basic"のパターンと呼ぶことにしています。

KARTEの基本的な使い方(データフロー)は大まかには次のような流れです。

  1. クライアントのウェブサイトやアプリに訪問しているエンドユーザーは、KARTEの"TRACK"というシステムに"イベント"データを送信する
    • 事前にクライアントのウェブサイト/アプリに埋め込んだ計測タグ(JavaScript)を埋め込んでいます
  2. "TRACK"システムは"イベント"をリアルタイムに解析して、そのエンドユーザーに合わせた"アクション"をレスポンスとして返す
    • "アクション"はバナー、ポップアップ、アンケートなどさまざまな種類の接客に関するデータを返します
    • この"アクション"は管理画面上で、KARTEを利用するクライアントが定義します
  3. エンドユーザーは、受け取った"アクション"のレスポンスを元に接客を表示する

KARTEの基本的な使い方

まずはこの"Basic"のパターンに関するデータフロー図を描いてみて進めてみました。
今回はdraw.io(diagrams.net)を使ってデータフロー図を作成しました。
データフロー図には、流れるデータの大まか種類や大まかなデータの保存場所、アクター(登場人物)などを描き加えています。

KARTEのデータフロー Basicのフロー

実際の脅威分析で利用したKARTEのデータフロー図(Basic)

このデータフロー図といくつかのテンプレートを組み合わせてしっくりくるものがあるかを何種類で試してみました。


📝試行錯誤のメモ

この時の記憶としては、図はかなり重要でちょっと面倒でも描いた方がいいとは思いました。
図によってデータの流れが改めて可視化されることによって気づくこともあるためです。

一方で、どこまで詳細に書くべきかは実際に行う脅威分析と併せて解像度のレベルを決めた方が良さそうでした。
KARTEの脅威分析では、クライアントのサイトやKARTEの管理画面のように大まかなコンポーネントにした図を描きました。
GCPとかAWSとかそういう実際のサービスは出さないで、論理的な構成図で進めたことが、脅威分析の負荷を減らすに役立ちました。

気をつけるべきことは、この脅威分析では図を作ることが目標ではないという意識をもつことです。
つまり図は成果物ではなく副産物です。


脅威分析のやり方を模索して決める

脅威分析のやり方を決める際には、いくつかの脅威分析のパターンに当てはめながら考えていました。
たとえば、経路ごとに番号を振って、その番号が通る組み合わせにおいての脅威を考えるパターンです。
この方法だと番号の組み合わせ(経路の組み合わせ)が膨大になりすぎてわかりにくくなったり、複雑すぎると判断して別の方法を考えました。

経路ごとに番号を振った図

経路ごとに番号を振って、番号の組み合わせから分析しようとした図

ソースとシンク

組み合わせが膨大になリすぎる問題を回避するために、入力(ソース)と出力(シンク)に着目するのはどうだろうという話になりました。
たとえば、KARTEではクライアントのサイトを訪問したエンドユーザーのブラウザからイベントデータをKARTEのTRACKというサーバシステムに送信します。
そして、TRACKサーバはレスポンスとしてポップアップやアンケートフォームなどの接客データなどが含んだメッセージを返し、エンドユーザーのブラウザ上で接客を表示します。

この場合の、入力(ソース)はエンドユーザーのブラウザで、出力(シンク)も接客が表示されるエンドユーザーのブラウザです。
この入力(ソース)と出力(シンク)を経路に組み合わせて見ると、実際の発生するデータの流れと関連付けが簡単にできそうだとわかりました。

ソースとシンクを入れた図

ソースとシンクを入れた脅威分析の図

データフローをパターンに分ける

この頃になると、KARTEの脅威分析ではデータフローに着目するのがいいのではないかというのが見えてきました。
図に実際の詳細な構成を落とさないようにしていたのもありますが、特定のコンポーネントに掘り下げるといつまでも終わらない可能性がありました。
そのため、細かすぎることにこだわりすぎるより、ある程度抽象化したデータフローを基にして脅威を分析していく形が現実的でした。

KARTEのBasicなパターンでは、データフローは大きくわけると次の3つのパターンとなります。

  • クライアントサイトのエンドユーザーがイベントを送り、KARTEのTrackサーバがイベントを分析して、その結果を接客として返すフロー
    • クライアントのエンドユーザー ↔ KARTEのシステム
  • KARTEのクライアントがKARTEの管理画面で接客テンプレートの変更などをフロー
    • クライアント ↔ KARTEのシステム
  • クライアントサイトのエンドユーザーがイベントを送り、KARTEのクライアントが管理画面でそのイベントを確認するパターン
    • クライアントのエンドユーザー ↔ クライアント

これらの3つのパターンに分けてデータフローを分析していくことにしました。

なぜパターンを分けたのかというと、登場人物(アクター)が違う点やそもそも1つの図にデータフローを複数書いていくと複雑になりすぎるためです。
データフローをパターンごとに分ける工夫としては、draw.io(diagrams.net)のレイヤー機能を使いパターンごとにデータフローをON/OFFできるようにしています。

draw.ioのレイヤー機能でデータフローの切り替えの活用

信頼境界線を引く

さきほどのパターンで登場するのは大まかにわけるとクライアントのエンドユーザー、クライアント、KARTEのシステムです。
これらの間には信頼境界線が引けます。
信頼境界線とは、その線を境にして信頼レベルが異なる領域を区切る線のことです。
たとえば、クライアントのエンドユーザーには普通のユーザから攻撃者までさまざまです。
一方で、KARTEのシステムはKARTEの開発者が扱うため、エンドユーザーとは信頼レベルは異なると考えるのが妥当です。

先ほどの図にも薄く信頼境界線が書かれていましたが、クライアントのエンドユーザー(End User)/クライアント(Client User)/KARTEのシステムにおける信頼境界線は次のようになります。

信頼境界

注意点としては信頼境界線の中であるからといって、その中のものがすべて信頼できるわけではありません。
たとえば、システム同士の通信を扱う場合に内部的な通信であっても、その通信を検証する方が安全です。
この辺は、ゼロトラストネットワークなども参照すると良いです。

セキュリティ的な問題はこの信頼境界線をまたぐ際に発生しやすいです。
たとえば、エンドユーザーからリクエストをKARTEのシステムが受け取る際には、信頼境界線をまたいでいます。
この時のリクエストが何らかの脆弱性をつくものである場合を考えると、KARTEのシステムに対する脅威があると言えます。

ここまでをまとめると次のようになります。

  • 実際の入力(ソース)と出力(シンク)からデータフローを作成した
  • データフローにおける登場人物(アクター)によってパターンを3つにわけた
  • 信頼境界線を引き、その境界をまたぐデータフローに注目した

📝 信頼境界線を引くべきかどうか

信頼境界線を引くことが正しいというわけでもありません。
信頼境界線を引かずに、すべては信用できないものとして考えて、進めていくのも分析としては正しいはずです。
ただし、その場合には考える組み合わせが膨大になるため、何らかの線引きが必要になります。

また、信頼境界線の中だからといって脅威がないわけではありません。
今回の脅威分析でも、信頼境界線内(つまりシステムからシステム)における脅威として、ログに意図しない情報を出力してしまうこと脅威を発見しています。

この脅威分析で重要だと考えていたのは、現実的な時間やコストで回せるようになることです。
脅威分析が一番大事というわけではなく、セキュリティ対策の一環として回るようになることを目標にしています。
そのためには、常に適した形を模索していく必要があります。


脅威分析で脅威を探してみる

ここまで次の要素が図から見つけられるようになったので、具体的な脅威を見つけて、実際にその脅威におけるリスクを考えていきます。

  • 登場要素によるデータフローのパターン分け
  • 入力(ソース)と出力(シンク)
  • 信頼境界線

信頼境界線を引き、入力(ソース)と出力(シンク)を見ていくと、脅威が見つけやすくなると考えられます。
実際のデータフロー図と信頼境界線の行き来を見ることで、図における経路は大まかに管理できます。
その経路に対する具体的なソースとシンクを書けば、具体的な経路も管理できます。

この信頼境界線とソース/シンクの組み合わせを経路番号の代わりに使うことで、データフローの管理を単純化しています。

具体的には次のようなデータフロー図と脅威分析シートを組み合わせて管理しています。

データフロー図: End User to System

データフロー図: End User to Systemのパターン

クライアントのエンドユーザー ↔ KARTEのシステムのデータフローにおける脅威分析シートの一部を取り出したものです。

No 信頼境界外 信頼境界内 信頼境界外 ソース シンク 脅威 攻撃経路 攻撃例
1 x x - End Userのブラウザ システム内部 内部情報の改ざん 脆弱性をついた攻撃 Trackサーバに対するRCE
2 x - x インターネット通信 インターネット通信 End User情報の漏洩 通信路上の盗聴 通信内容を解読される
3 - x x システム内部 End Userのブラウザ 内部情報の漏洩 バグ 設定ミス、実装不備等による誤配信

No.1は、信頼境界外から信頼境界内へのデータフローにおける例です。

  • このときのソースがエンドユーザーのブラウザで、シンクはシステム内部
  • エンドユーザーからシステムに対してリクエストが行われる場合における脅威としては、内部情報の改ざんが考えられる
  • 内部情報の改ざんという脅威攻撃経路としては脆弱性を付いた攻撃が考えられる
  • この攻撃例としては、Trackサーバに脆弱性がありRemote Command Executionを行うといった可能性が考えられる

このように、信頼境界とソース/シンクを元に脅威を考えて行けるようになっています。
最初のすべての経路に番号を振って、その番号を追うように考えていくよりはかなり単純化しています。

また、脅威を一から考えるのは頭を使うため、STRIDEと呼ばれる脅威モデリング手法で定義されている6種類の脅威を参考に使っています。
先ほどのNo.1では、エンドユーザーからシステムへのリクエストにおいて、なりすまし・改ざん・否認・情報漏えい・サービス拒否・特権の昇格のうちおきる可能性があるものはどれかといった形が考えていきます。脅威の例として"改ざん"は可能性としてありそうで、実際にそれを行うには何かしらの脆弱性突く必要があるというように進めていくイメージです。

脅威のリスクを評価する

それぞれのデータフローにおける脅威が見つけられたら、それが実際にリスクなのかどうかを判断しないといけません。
リスクの評価は分析手法や分析するものによっても判断基準は異なります。

たとえば、IPAが公開している制御システムのセキュリティリスク分析ガイド 第2版では次のようなリスクの評価基準を定義しています。事業被害ベースのリスク分析では次のような要素を組み合わせています。

被害の大きさ(資産の重要度) x 脅威の発生可能性(脅威が発生するかどうか) x 脅威が起きた時の成功の可能性(対策できているかどうか)

KARTEの脅威分析では、以前から社内で利用していたIssueにセキュリティラベルをつける際の判断基準を参考にして、その脅威のリスクを評価しました。

社内でセキュリティラベルをつける際の判断基準に利用していたテーブルは簡略化すると次のような形です。

攻撃難易度 \ 影響度
簡単 Low High Critical
普通 Low Medium High
難しい Low Low Medium

ここで少し困った点として、脅威分析における脅威とは実際に存在している問題ではなく、あくまで可能性としてありえる程度のものがでてきます。
そのため、具体的なIssueに比べると抽象的なものが多く、その攻撃難易度(容易性)は判断しにくいという問題がありました。

そのため、実際にリスクを評価する際には、その脅威が実際に発生した場合の被害の大きさも含めるのが良さそうです。
つまり先ほどの事業被害ベースの分析手法に近い形となりました。

被害の大きさ(資産の重要度) x 脅威の発生可能性(脅威が発生するかどうか) x 脅威が起きた時の成功の可能性(対策できているかどうか)

具体的な例を見てみましょう。

No 信頼境界外 信頼境界内 信頼境界外 ソース シンク 脅威 攻撃経路 攻撃例 影響例 対策
1 x x - End Userのブラウザ システム内部 内部情報の改ざん 脆弱性をついた攻撃 Trackサーバに対するRCE xxx xxx
2 x - x インターネット通信 インターネット通信 End User情報の漏洩 通信経路上の盗聴 通信内容を解読される Cookieを盗んでなりすましが可能 HTTPS化
3 - x x システム内部 End Userのブラウザ 内部情報の漏洩 バグ 設定ミス、実装不備等による誤配信 xxx xxx

No.2の End User情報の漏洩という脅威の例では、通信経路上の盗聴という攻撃経路の可能性を検討しています。
盗聴ができるとそのEnd UserのCookieを盗み出してなりすましが可能という影響が考えられます。
しかし、実際にはKARTEへの通信はHTTPSであり、対策済みと言えます。
そのため、リスクの評価結果は小さいと考えられます。

このようなことを脅威のパターンごとにくりかえしてリスクを評価していきます。
リスクを評価することで、脅威ごとのリスクを相対的な値(Low, Middle, High, Criticalなど)で判断できるようになります。

このリスクの評価結果は、脅威分析の目的でもあるどのリスクから対応していくかの優先度の判断に利用できます。これは最初に書いていた脅威分析をした目的でもあります。

セキュリティにおいてリスクがなくなることはありません。
一方でセキュリティの問題に対応していくリソースは無限でないため、どこからやるべきなどの優先順位をつけることが重要です。
この優先順位をつけるために、どこにどの程度のリスクが存在するのかを相対的に把握必要がありました。

リスクの評価結果がCriticalであるなら、事業への影響度も高い可能性があり、かつ対策が不十分な脅威といえます。
このような脅威に対して優先的に対策を考えていくことで、システム全体としてのリスクを減らしていけます。


📝脅威分析はセキュリティチームに閉じてやらない

脅威分析をやる際に重要なことはそのシステムに詳しい人と一緒にやることです。
セキュリティチームだけに閉じてやるのは良くありません。実際に開発している人を巻き込んだ形で進めるのが良いです。

PLAIDではセキュリティ組という形で、色々なチームの人が集まった状態で行っています。
今回の脅威分析でも、セキュリティ組が中心となって進めていましたが、脅威分析においてはそのシステムについて詳しい人を呼んで話を聞きながら進めていました。
セキュリティに詳しい人がそのシステムのドメインに詳しいとは限らないため、詳しい人を呼ぶ形でやるのが確実です。

これはDomain-Driven Designにおけるドメイン知識を探す発想と似ています。

次の記事でも開発者を巻き込んだ形で、簡単なものから初めていく脅威モデリングのアプローチについて書かれています。

最初に述べていますが、脅威分析をやることは目的ではありません。
分析した結果から対策し、リスクを減らしていくのが目的です。
このような全体のサイクルを考えていくと、セキュリティチームに閉じている状況は不自然であるため、避けるべきです。


脅威分析の結果をIssueにして対策していく

実際に脅威分析をしてリスクの評価結果がHighやCriticalの脅威から優先的に対策を考え、GitHubにIssueを作成して対策していきました。
脅威分析によってリスクが相対的に評価できる状態となったため、優先度が高いものからIssue化できます。
これは脅威分析をやろうとした目的でもあります。

また、すべての脅威に対して具体的な対策ができるわけではありません。
実際に発生する影響度が大きくCriticalなラベルの脅威があったとしても、直接的な対策が難しい場合もあります。

たとえば、管理画面へのクライアントのID/PASSを使った不正アクセスなどがあります。
この脅威は実際に発生すると影響が大きいですが、IDとPASSを決めるのはクライアントユーザーであるため確実に回避する方法はありません。
しかし、リスクを減らす方法としてログイン通知・不正ログインの検知・弱いパスワードを登録できなくする・2要素認証の必須化などさまざまな方法があります。それらの方法を組み合わせてリスクを許容できるレベルまで落としていくというのも対策です。

弱いパスワードを登録できなくする例として次のようなケースもあります。

対策した結果を新しく反映する

この記事を書いている現時点では、対策を実装している最中であるため、まだ次のサイクルまでは行っていません。

セキュリティ設計のサイクル

今回の脅威分析にご協力頂いたEGセキュアソリューションズ株式会社さんとともに脅威分析の反省会を行い課題もでてきました。

ここまで大規模に実施した脅威分析は今回が初めてだったのもあり、ある程度長いスパンで行っていました。
しかし、このスパンをもっと短くしないとサイクルとして回すのが難しいという課題があります。

短くする方法としては、脅威の差分だけに着目する方法があります。
次の脅威分析では、新しくできたもの変更があったものだけについて分析していくなどといった形です。
すでにあるシステムで行った脅威分析を別システムに横展開していく場合にも同じやり方が通用します。

短くする別のパターンとしてはもっと別のフォーマットで行う方法が考えられます。
今回はSpreadSheetのようなテーブルにデータを入れていく形で行いましたが、実際の開発に使うツール上で行うのが適していると考えています。
たとえば、GitHubのProject機能を使って脅威を管理していくなども考えられます。(一覧性などの情報量としては減ってしまう可能性はあります)

これはどんなに優れたツール、手法であっても、実際に使われないと意味がないためです。
そのため、セキュリティ対策のサイクルとして脅威分析という手法自体に強くこだわる必要はないはずです。

まとめ

セキュリティのリスクに対して、優先度をもって対応していくためにKARTEの脅威分析しました。

脅威分析では一緒に開発している人(つまり詳しい人)に聞きながらやることで、改めてデータフローなどを俯瞰的に把握できるものがありました。
脅威分析をおこない実際に見つけた脅威への対策なども継続的に行っていくことでセキュリティの向上に繋がります。
また、脅威分析ではセキュリティについて話すときにどのような着目点で話すとがリスクを見つけやすいかなどの発見がありました。

一方で図や表といった資料を作ることが目的ではないため、そこは常に意識してやっていく必要があります。
リスクを分析するコスト(時間的、心理的)をどれぐらい下げられるかが今後サイクルとして回すためには考えていくべき課題です。

今回はすでに動いているKARTEのシステムに対して脅威分析をしました。
脅威分析はこれから新しく作るプロダクトのほうが発見できることは多いはずです。
そのため、これからもやり方は変えつつ開発のサイクルに溶け込むような形を模索していきます。

謝辞

今回のKARTEの脅威分析において、EGセキュアソリューションズ株式会社の徳丸さん、岡本さん、松本さん、佐藤さんにご協力いただきました。

KARTEに適した脅威分析の形を議論しながらすすめることができました。

ここに感謝申し上げます。

参考

最後に

CX(顧客体験)プラットフォーム「KARTE」を運営するプレイドでは、継続的なセキュリティ対策に取り組んでいきたいというエンジニアを募集しています。
詳しくは弊社採用ページまたはWantedlyをご覧ください。 もしくはお気軽に、下記の「話を聞きに行きたい」ボタンを押してください!