どの脅威モデリング手法も、同じ問いから始まります。「私たちは何に取り組んでいるのか?」という問いです。その答えとしてよく使われるのが、データフロー図です。5 種類の要素だけで描けるシンプルな図ですが、セキュリティレビューの前の 1 時間をこれ以上有効に使える方法はありません。脅威の多くは、データがある信頼レベルから別の信頼レベルへ移る場所に潜んでいるからです。
このガイドでは、脅威モデリングのためのデータフロー図(DFD)の描き方、信頼境界の置き方、そして STRIDE に沿って図をたどる方法を紹介します。例として取り上げるのは、ほぼすべてのプロダクトにある機能、ユーザーによるプロフィール写真のアップロードです。
4 つの問い
実践的な脅威モデルは、Adam Shostack と Threat Modeling Manifesto によって広まった 4 つの問いに答えます。
- 私たちは何に取り組んでいるのか?
- 何がうまくいかない可能性があるか?
- それに対して何をするのか?
- 十分にうまくできたか?
データフロー図は 1 つ目の問いに答えます。STRIDE は 2 つ目の問いに答える助けになります。図に添えるメモやチケットが 3 つ目の問いに答え、数週間後のレビューが 4 つ目の問いに答えます。
データフロー図の要素
| 要素 | 内容 | 一般的な形 |
|---|---|---|
| 外部エンティティ | 自分たちの管理外にある人やシステム。ユーザー、パートナーの API など | 長方形 |
| プロセス | データを変換したり移動したりする、自分たちが実行するコード | 円または角の丸い図形 |
| データストア | データが保存されている場所。データベース、バケット、キュー、ログなど | 2 本の平行線または円柱 |
| データフロー | 2 つの要素の間を移動するデータ | 運ぶデータのラベルを付けた矢印 |
| 信頼境界 | 信頼のレベルが変わる場所 | 破線、または要素を囲むゾーン |
DFD をセキュリティに役立てるためのルールが 2 つあります。1 つ目は、すべてのフローにプロトコルだけでなく、運ぶデータのラベルを付けることです。photo + session token は HTTPS よりもはるかに多くのことをレビュー担当者に伝えます。2 つ目は、データストア同士や外部エンティティ同士を決して直接つながないことです。データは必ずプロセスを経由して移動し、そこがデータを検査できる場所になります。
例: プロフィール写真のアップロード
ユーザーはブラウザーからプロフィール写真をアップロードします。Web API はセッションを確認し、元のファイルを非公開のバケットに保存します。アップロード処理サービスがそのファイルを取り出してバイト列をサードパーティのマルウェアスキャン API に送り、画像を再エンコードしてメタデータを削除し、クリーンな版をバケットに書き戻してから、写真の URL をユーザーデータベースに記録します。
信頼ゾーンは 4 つあります。インターネット、自社のアプリケーション層、自社のデータ層、そしてサードパーティのスキャナーです。DFD として描くと次のようになります。
ダイアグラムの内容
- Trust zone: internet
- Trust zone: app tier
- Trust zone: data tier
- Trust zone: third party
- User's browser
- Web API
- Upload processor
- Photo bucket (private)
- Users DB
- Malware scan API
- photo + session token
- raw photo
- clean image, no metadata
- file bytes
- verdict
- photo URL + status
ゾーンの境界をまたぐフローを数えてみましょう。ブラウザーから API、API からバケット、バケットと処理サービスの往復、処理サービスとスキャナーの往復、そして処理サービスからデータベースです。時間をかけるべきなのは、こうした箇所です。
STRIDE に沿って図をたどる
STRIDE は脅威を 6 種類に分類して名前を付けたものです。Microsoft の「要素ごとの STRIDE」(STRIDE per element)というアプローチでは、各要素について、その種類に当てはまる脅威だけを確認します。
| 要素の種類 | S | T | R | I | D | E |
|---|---|---|---|---|---|---|
| 外部エンティティ | ✓ | ✓ | ||||
| プロセス | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| データストア | ✓ | ✓(ログ) | ✓ | ✓ | ||
| データフロー | ✓ | ✓ | ✓ |
6 つの文字は、なりすまし(Spoofing)、改ざん(Tampering)、否認(Repudiation)、情報漏えい(Information disclosure)、サービス拒否(Denial of service)、権限昇格(Elevation of privilege)を表します。アップロード機能を要素ごとにたどっていくと、次のようなリストになります。
- なりすまし(ブラウザー)。 盗まれた、または偽造されたセッショントークンを使って、他人の名義で写真がアップロードされます。対策:すべてのリクエストでトークンを検証し、セッションの有効期間を短くし、オブジェクトキーはリクエスト内の値ではなく、必ず認証済みユーザーの ID に結び付けます。
- 改ざん(バケットから処理サービス)。
photo.jpgという名前なのに、中身はまったく別のファイルです。対策:ファイル名や申告された種類ではなく、ファイルの実際の形式を確認し、ほかの誰かの目に触れる前にすべての画像を再エンコードします。 - 否認(API)。 ユーザーが不快な画像をアップロードしたことを否定し、それを覆す証拠が何もありません。対策:アップロードのたびに、ユーザー ID、オブジェクトキー、時刻、クライアントのアドレスをログに記録します。
- 情報漏えい(バケット)。 バケットの一覧が公開されている、あるいは写真の EXIF メタデータに GPS 座標が残っています。対策:有効期限の短い署名付き URL で配信する非公開バケットと、再エンコード時のメタデータ削除です。
- サービス拒否(API と処理サービス)。 巨大なファイルや、展開すると膨大なサイズになる画像がメモリを使い果たします。対策:ファイルサイズとピクセル数の上限、そして処理サービスでのタイムアウトです。
- 権限昇格(処理サービス)。 細工されたファイルが画像ライブラリのバグを突き、処理サービスの権限でコードを実行します。対策:処理サービスをサンドボックスで実行し、自身のバケットプレフィックスと専用のテーブル 1 つ以外には一切アクセスできないようにします。
脅威は、影響を受ける要素の横にメモを置き、番号付きの短い行として書き込みます。それぞれの脅威は、修正を追跡するチケットにリンクします。こうすれば、図がそのままレビューのまとめにもなります。
脅威モデリング図のルール
- 会社全体ではなく、機能を描く。 DFD は機能ごと、またはサービスごとに 1 枚です。すべてを詰め込んだ図には、重要な詳細を書き込む余地がありません。
- 認証が行われる場所を示す。 境界をまたぐフローごとに、ID を検証するプロセスに印を付けます。
- 誰もデモで見せない経路も含める。 管理ツール、サポートによるアクセス、バッチジョブ、バックアップも境界をまたぎます。
- 詳細度を 1 つにそろえる。 コンテキストレベルの DFD はシステムを 1 つのプロセスとして示し、レベル 1 の DFD はそれを主要なプロセスに分解します。1 枚の図ではどちらか一方を選びます。
- 機能と一緒にバージョン管理する。 設計が変われば脅威も変わります。設計ドキュメントと同じプルリクエストで図も更新しましょう。
専用ツールか、共有キャンバスか
OWASP Threat Dragon や Microsoft Threat Modeling Tool などの無料ツールは、まさにこの作業のために作られており、要素ごとに脅威を提案してくれます。セキュリティチームがプロセスを主導する場合にはうまく機能します。
機能を作るメンバーが設計の段階で一緒に図を描くなら、共有キャンバスのほうが向いています。DFD がアーキテクチャ図の隣に置かれ、全員がライブで編集でき、メモは要素に添えられたまま残ります。どちらを選んでも、本当に価値があるのは図を囲んで交わされる議論です。
Archboard で作成する
- Google または GitHub でサインインし、図を作成します。
- 信頼ゾーンごとに基本パックのフレームを追加し、
Trust zone: app tierのようにゾーン名を付けます。 - 外部エンティティは基本パックのボックスノード、プロセスは同じく基本パックの楕円シェイプ、データストアはデータパックのノード(オブジェクトストア、Postgres)で追加します。
- ポート同士を接続し、すべてのエッジに運ぶデータのラベルを付けます。
- 影響を受ける要素の横にメモを追加し、各脅威を STRIDE の文字、番号、チケットとともに列挙します。
この例では 10 ノードに加えて、7 つの脅威を記したメモを 3 つ使っており、Free プランの範囲内に収まります。セキュリティのネットワーク面についてはゼロトラストアーキテクチャ図のテンプレートを、個人データのマッピングについてはGDPR データマッピング図のユースケースを参照してください。
よくある質問
データフロー図はアーキテクチャ図と同じものですか? いいえ。アーキテクチャ図はコンポーネントとそのつながりを示し、DFD はデータがどう移動し、どこで信頼が変わるかを示します。同じボックスが登場することも多いですが、DFD はセキュリティの問いに答えるために描くものです。
STRIDE と別の手法、どちらを使うべきですか? ソフトウェアの機能には、STRIDE がよい標準の選択肢です。LINDDUN はプライバシーの脅威に焦点を当てており、PASTA は大規模な取り組み向けのリスク中心のプロセスです。どの手法でも、出発点は同じ図です。
誰が参加すべきですか? その機能を作るエンジニア、運用を担う人、そしてセキュリティエンジニアがいればその人です。脅威を見つけるのはコードを知っている人たちで、セキュリティエンジニアは確認が形だけで終わらないよう目を光らせます。
どのくらい時間がかかりますか? 写真アップロードのような機能なら、1 時間が目安です。図を描くのに 15 分、STRIDE に沿ってたどるのに 30 分、修正内容と担当者を決めるのに 15 分です。
モデルはどのくらいの頻度で更新すべきですか? フローが新しい境界をまたぐとき、新しいデータストアが加わるとき、または機能の変更で誰が何をできるかが変わるときです。