はじめに
本書『Security Development Lifecycle』(Michael Howard・Steve Lipner 著、Microsoft Press)は、Microsoftが社内で実践してきたセキュリティ開発プロセス「SDL(Security Development Lifecycle)」を体系的にまとめた書籍です。
Windowsをはじめとする大規模ソフトウェア製品において、どのように脅威を分析し、セキュアな設計・実装・テスト・リリースを実現するかを、ステージごとに具体的な手法とともに解説しています。
本書はMicrosoftが2002年の「Trustworthy Computing」宣言以降に構築したSDLを公開したもので、業界全体に多大な影響を与えました。
なぜSDLが必要なのか
脅威の変化
インターネットが普及した現代において、攻撃者の動機と手口は大きく変化しています。かつての愉快犯的なハッキングから、金銭目的のサイバー犯罪、国家レベルの組織的攻撃へと進化しました。
本書ではこの変化を「Enough Is Enough: The Threats Have Changed(もうたくさんだ:脅威は変化した)」として第1章で取り上げています。匿名のインターネット攻撃が増え、アプリケーション開発者がセキュリティ問題に気付かないまま製品を出荷するリスクが高まっていると指摘しています。
品質問題としてのセキュリティ
本書の重要なメッセージのひとつは、セキュリティはコードの品質問題であるということです。
バグのないコードを目指すのと同様に、セキュリティも設計から実装・テストまで一貫して組み込む必要がある
コードレビューへのインセンティブ設計(Microsoftセキュリティ情報との関連付け)、"Many Eyeballs"神話への反論(多くの目があればバグは見つかるという考えが商用ソフトウェアでは通用しない事実)など、開発現場の現実に即した議論が展開されます。
SDLの全体構造
SDLは以下のステージで構成されています。
| ステージ | 名称 | 概要 |
|---|---|---|
| Stage 0 | 教育と認識 | 全開発者へのセキュリティトレーニング |
| Stage 1 | プロジェクト開始 | SDL適用判断、キックオフ、バグトラッカー設定 |
| Stage 2 | 設計ベストプラクティス | 攻撃対象領域分析と縮小、設計原則の定義 |
| Stage 3 | 製品リスク評価 | セキュリティ・プライバシーリスクのランキング |
| Stage 4 | リスク分析 | 脅威モデリングの実施 |
| Stage 5 | セキュリティドキュメント作成 | 顧客向けガイド・ベストプラクティス |
| Stage 6 | セキュアコーディングポリシー | 禁止関数・コンパイラオプションの規定 |
| Stage 7〜9 | セキュリティテスト | ファジング・侵入テスト・コードレビュー |
| Stage 10 | セキュリティ対応計画 | SSIRP策定、対応チーム編成 |
| Stage 11 | 製品リリース | 最終セキュリティレビュー(FSR) |
Stage 0 : 教育と認識
SDL導入の前提として、開発者全員がセキュリティの基礎を習得することが求められます。
本書では、Microsoftにおけるセキュリティ教育の小史として、DESの仕組みや暗号の基礎から、攻撃対象領域分析(ASA)・攻撃対象領域縮小(ASR)のクラス受講義務化まで、段階的な教育プログラムの整備過程が紹介されています。
- 出席状況のトレーニングコンプライアンス追跡を行う
- 継続的な教育(設計・ASA/ASR・STRIDE・暗号など)を実施する
Stage 1 : プロジェクト開始
SDL適用の判断基準
すべてのプロジェクトがSDLの完全適用対象になるわけではありません。ドットリリース(マイナーアップデート)と大規模リリースでは適用範囲が異なります。
プロジェクト開始時のチェックポイントは以下のとおりです。
- アプリケーションがSDL対象かどうかの判断
- 開発チーム向けSDLキックオフミーティングの開催
- バグ追跡プロセスにセキュリティ・プライバシー用のバグフィールドを追加する
- セキュリティバグの重大度(バグバー)定義済み値の設定(攻撃対象領域縮小・DoS・情報開示・ディレクトリトラバーサルなど)
セキュリティアドバイザーの役割
開発チームのセキュリティ相談役として、セキュリティアドバイザーがFSR(最終セキュリティレビュー)の準備やセキュリティポリシーの周知を担います。
Stage 2 : 設計ベストプラクティスの定義と遵守
攻撃対象領域分析(ASA)と縮小(ASR)
攻撃対象領域(Attack Surface)とは、信頼されていないユーザーがアクセスできるコードやインターフェイスの総体です。SDLでは以下の3ステップで攻撃対象領域を評価・縮小します。
ステップ1:この機能は本当に必要か?
デフォルトで無効化できる機能や、使用頻度の低い機能は無効化を検討します。フェイルセーフ設計が基本です。
ステップ2:誰がどこからアクセスする必要があるか?
- 匿名アクセスと認証済みアクセスの区別
- ローカル・リモートの区別
- グループメンバーシップの検討
ステップ3:権限の削減
- 最小権限の原則に基づき、管理者権限で動作するプロセスを減らす
- 複数の実行可能プロセスへの分割
- Apacheアカウントや非管理者アカウントでの実行を推奨
ActiveXの扱いに関する注意
ActiveXコントロールの「スクリプトを実行しても安全」マーク付けは攻撃対象領域を大幅に拡大します。AllowPartiallyTrustedCallers属性(APTCA)の使用も慎重な判断が必要です。
共通セキュア設計原則
本書で示される設計原則のポイントは以下のとおりです。
- メカニズムの経済性:設計をシンプルかつ小規模に保つ
- 完全な調停:すべてのオブジェクトへのアクセスを検証する
- 多層防御:防御メカニズムを複数層に重ねる
- グローバル変数よりローカル変数:スコープを最小化する
- McCabe循環的複雑度の管理(複雑すぎるコードはレビューが困難)
Stage 3 : 製品リスク評価
プライバシーランキング(1〜5など)を用いて製品の機密性リスクを定量化します。評価観点は以下のとおりです。
- 個人情報(PII)の保存・転送の有無
- 子供向けコンテンツへの対応
- 匿名データと識別データの混合・相関の有無
- 自動的に収集されるデータの範囲
- モバイルコードの有無
これらの質問(セキュリティリスク評価アンケート)への回答をもとに、開発リソースの集中投下箇所を判断します。
Stage 4 : 脅威モデリング
SDLの中核をなすのが脅威モデリングです。DFD(データフロー図)を用いてシステムを可視化し、STRIDE手法で脅威を体系的に洗い出します。
DFDの構成要素
| 要素 | 説明 |
|---|---|
| 外部エンティティ | システム外部のアクター(ユーザー、外部サービス) |
| プロセス | データを処理する内部ロジック |
| データストア | DBやファイルなどデータを保持する場所 |
| データフロー | 要素間のデータの流れ(矢印) |
信頼境界(Trust Boundary)をDFD上に明示することで、攻撃対象を絞り込めます。
STRIDE脅威分類
| 頭文字 | 脅威カテゴリ | 説明 |
|---|---|---|
| S | Spoofing(なりすまし) | 外部エンティティ・プロセスのなりすまし |
| T | Tampering(改ざん) | データフロー・データストアの不正変更 |
| R | Repudiation(否認) | 監査ログの脆弱性による行為の否認 |
| I | Information Disclosure(情報開示) | データストア・フローからの情報漏洩 |
| D | Denial of Service(サービス拒否) | プロセス・データストア・フローへのDoS |
| E | Elevation of Privilege(権限昇格) | 低権限から高権限への不正昇格 |
リスク評価:DREAD
洗い出した脅威に対してDREAD評価でリスクを数値化します。
- Damage(被害の深刻度)
- Reproducibility(再現性)
- Exploitability(攻撃の容易さ)
- Affected Users(影響ユーザー数)
- Discoverability(発見のしやすさ)
緩和戦略の検討
STRIDEの各脅威カテゴリに対して技術的な緩和策を設計します。たとえばなりすましには認証強化、改ざんにはデジタル署名、情報開示にはDPAPI(データ保護API)の活用などが例として挙げられています。
「何もしない」という戦略も選択肢のひとつですが、その場合はリスクの明示的な受容が必要です。
Stage 5 : 顧客向けセキュリティドキュメント作成
顧客向けに以下のドキュメントを整備します。
- 規範的セキュリティベストプラクティスドキュメント:セットアップドキュメントとは別物として作成
- 外部セキュリティノート:セキュリティの前提と外部依存関係を明示
- ツールのドキュメント:セキュリティ設定ツールや自動更新の使い方
Pet Shop 4.0の事例では、ASP.NETアプリケーションのセキュリティ前提(DPAPIによる接続文字列保護・データベースサーバのネイティブ認証設定など)を外部セキュリティノートに記述する例が示されています。
Stage 6 : セキュアコーディングポリシー
禁止API・禁止関数
SDLでは使用を禁止または代替が必要な関数一覧(Banned API)を規定しています。代表的なものは以下のとおりです。
-
strcpy・strcat→ StrSafe関数(StringCchCopy等)またはSafe CRT関数で置き換え -
gets・sprintf→ サイズ指定版の関数へ移行 -
IsBad*系関数(IsBadReadPtr等)→ 使用禁止、代替手段を検討 -
makepath・splitpath等の文字列トークン化関数
Non-'n'関数と呼ばれる境界チェックのないC関数群が主な対象です。
必須コンパイラオプション(アンマネージドコード)
/GS スタックバッファオーバーランの検出
/SAFESEH 安全な例外ハンドラの登録
/NX(DEP) データ実行防止との互換性確保
/analyze 静的コード解析(Visual Studio 2005以降)
マネージドコードへの対応
FxCopによるセキュリティルールチェック、AllowPartiallyTrustedCallers属性の管理、マネージドコード固有のセキュリティ問題のレビューが求められます。
Stage 7〜9 : セキュリティテスト
ソースコード静的解析
- PREfast(Visual Studio /analyze):Cコードの欠陥検出
- FxCop:マネージドコードのセキュリティルール検証
- AppScan:Webアプリ向けの解析
静的解析ツールの限界も明記されており、ツールが見つけられない設計上の欠陥は別途コードレビューが必要です。
ファジング(Fuzz Testing)
入力データを意図的に異常・ランダムな値に変化させてアプリケーションの挙動を検証します。
ファイルファジングの一般的プロセス:
- 正常なファイルを用意する
- ファイルを破壊・変形した不正ファイル群を生成する(MiniFuzz等のツールを使用)
- アプリケーションに大量の不正ファイルを食わせる
- デバッガー・AppVerifで実行し、クラッシュを検出する
- クラッシュを引き起こしたファイルを保持して分析する
ネットワークプロトコルファジングのアプローチ:
- オンザフライでパケットを改ざんする(中間者ポジションで偽パケット生成)
- ASN.1のような複雑なプロトコルパーサーには特に重点的にファズテストを実施する
侵入テスト
- アプリケーション検証ツール(AppVerif)を使ったランタイム検証
- Microsoft Windows ドライバー検証ツールの活用
- 脆弱性発見後の欠陥バリアント調査(同一コード領域内での類似バグの確認)
コードレビュー
脅威モデルを活用してレビュー対象を絞り込みます。アーキテクトが脅威モデルをレビューし、攻撃対象領域のスクラブ(ドキュメント更新・不要機能の削除)を実施します。
Stage 10 : セキュリティ対応計画(SSIRP)
製品リリース前に、脆弱性対応プロセス(SSIRP: Security Security Incident Response Process)を策定します。
SSIRPのフェーズ
警戒・動員フェーズ → 評価・安定化フェーズ → 解決フェーズ → 更新リリース
- 監視フェーズ:メーリングリスト・セキュリティ研究者からの情報収集
- トリアージ:脆弱性の深刻度評価(MSRCセキュリティ情報評価システムを使用)
- 修正の作成:開発チームによるパッチ作成、テスト、コンテンツ制作
- 緩和策と回避策の提供:完全な修正が難しい場合の暫定対応
対応チームの編成
- 当直職員(On-call)の設置
- セキュリティ研究者との関係管理(信頼関係の構築と情報共有)
- 報道機関への積極的なアウトリーチ
- 製品更新の自動配信(Windows Update等)の活用
Stage 11 : 製品リリースと最終セキュリティレビュー(FSR)
出荷前の最終チェックポイントとして、FSR(Final Security Review)を実施します。
- 攻撃対象領域スクラブの完了確認
- 脅威モデルの最新化
- セキュリティベストプラクティスドキュメントの最終確認
- デバッガーシンボルの中央内部サイトへのアップロード
アジャイル手法へのSDL適用
本書ではSDLをアジャイル開発に統合する方法も検討されています(MSNやMessengerプロジェクトの事例を含む)。
ポイントは以下のとおりです。
- プロジェクト開始時にDFDを設計スプリントの成果物として作成する
- リスク分析をアジャイルのユーザーストーリーに組み込む
- セキュリティプッシュ:通常のイテレーションとは別に設けるセキュリティ専用のスプリント
- 小規模リリースの性質上、本格的なFSRを省略するケースもあるが、その場合でも最低限のSDLプラクティス(禁止API・コンパイラオプション・ファジング)は維持する
暗号に関するガイドライン
本書の後半では暗号アルゴリズムの選定基準も詳しく解説されています。
避けるべきアルゴリズム
- DES・DESX:すでに安全とはみなされない(SDL最小暗号化標準から除外)
- MD4・MD5:ハッシュ用途には使用しない
- RC4:ストリーム暗号として推奨されない
推奨アルゴリズム
- 対称ブロック暗号:AES(適切な鍵長とともに使用)
- 非対称暗号:RSA・DSAベースのデジタル署名
- 鍵共有:Diffie-Hellman
- MACには専用のMAC鍵長を使用する
秘密鍵と機密データの保管
GetRandom・GetTickCountは乱数生成には使用しない。DPAPIを活用して鍵・接続文字列・パスワードを保護します。
まとめ
『Security Development Lifecycle』は、セキュリティを「リリース直前に思い出すもの」から「開発の全ステージに組み込むもの」へ転換するための実践的なフレームワークを提供しています。
本書から得られる主要な学びをまとめます。
- 脅威は変化している:設計段階からセキュリティを考慮しなければ後から修正コストが膨大になる
- 攻撃対象領域の最小化:使わない機能を無効化し、最小権限で動作させることが基本
- 脅威モデリング:DFD × STRIDEの組み合わせが体系的な脅威洗い出しに有効
- 禁止APIの廃止:StrSafe等の安全な代替関数への移行を徹底する
- ファジングは必須:静的解析だけでは見つからないバグを動的テストで発見する
- セキュリティ対応計画の事前整備:脆弱性報告を受けたときに混乱しないためのプロセスを事前に定義する
SDLで登場するSTRIDE・DREAD・DFD・最小権限の原則などの概念は重要なキーワードです。ソフトウェア開発に携わるエンジニアに広くおすすめできる一冊です。