SDL の適用方法

マイクロソフトのセキュリティ開発ライフサイクルの内部検証

Michael Howard

この記事で取り上げる話題:

  • セキュリティ開発ライフサイクルの概要
  • 設計プロセスおよび開発プロセスにおけるセキュリティ
  • 脅威モデリングとテスト
  • セキュリティ レビューと対応
この記事で使用する技術:
セキュリティ開発ライフサイクル (Security Development Lifecycle)


目次

リーダーシップと教育
設計フェーズ
脅威モデリング (Thread Modeling)
開発フェーズ
セキュリティ テスト
セキュリティ プッシュ(Security Push) の開始
最終的なセキュリティ レビュー (Final Security Reviews)
セキュリティの対応
SDL が作動しますか


セキュリティ開発ライフサイクル (Security Development Lifecycle : SDL) は、現在マイクロソフトにより採用されていますが、その目標は 2 つあります。つまり、セキュリティ関連の設計およびコーディング上の欠陥数を減らすこと、および残存する欠陥の重大度を減らすことです。これは、マイクロソフトにて引用される"設計による安全性確保 (Secure by Design)、既定設計による安全性確保 (Secure by Default)、導入/展開時の安全性確保 (Secure in Deployment) およびコミュニケーション (Communication)" (SD3+C としても知られています) に準じています。SDL は、これらのうち、初めに述べた 2 つを主に重視しています。設計による安全性確保 (Secure by Design) は、最初から設計やコーディングの安全性を確保することを意味し、既定設計による安全性確保 (Secure by Default) は、セキュリティを完全に確保できないことを認識することです。現実的には、100% 正しいコードを作成できませんが、攻撃対象領域の減少について言う時は、特に後者が重要です。

この記事は、ユーザー独自のソフトウェア開発プロセスに SDL を適用する方法について説明しています。また、SDL の実装時にマイクロソフトで私達が学んだいくつかの演習をユーザーが受講する方法について説明します。したがって、ユーザー独自の開発プロセスにその概念を取り入れることができます。説明を始める前に、ソフトウェア開発の進め方に関する限り、SDL はプロセスに囚われないことを明確にしておきたいと思います。使用しているモデルがウォータフォール モデルであれ、スパイラル モデルであれ、小回りの利くモデルであれ、全く問題ありません。SDL から供給されるプロセス改善を使用できます。SDL はソフトウェア セキュリティの向上に結びつく方法を統合することにより、ソフトウェア開発組織のプロセスを変更します。セキュリティの欠陥を減少させることにより、SDL がソフトウェアの品質向上を実現することは、本当に素晴らしいニュースと言えます。

SDL では、既存のソフトウェア開発プロセスにセキュリティ固有のチェックや基準を追加しました。図 1 に、"ジェネリック" プロセスへの SDL のマップ方法を示しています。これで充分であれば、スパイラルの回りまたはウォータフォールの下に SDL を重ねてください。

主要な各フェーズを検証し、SDL を実装するために組織内で実行できることについて説明します。

リーダーシップと教育

私はマイクロソフトで SDL が成功した理由を聞かれることがあります。答えは簡単です。経営幹部のサポートと教育および自覚です。Bill Gates や Steve Ballmer が SDL に熱心に取り組んだことは極めて重要でしたが、同時に教育を受けた技術者の労働力が不可欠でした。

リーダーシップについては、セキュリティの中心人物となる一人または複数の人を指名する必要があります。任務としては、セキュリティ問題を完全に掌握し、開発組織でセキュリティを実践し、難しいセキュリティの判断をする時に理性の声を挙げることです。(この記事を読んでいるならば、リーダーシップをとる人はおそらく貴方です。) リーダーシップをとる人は、Bugtraq (www.securityfocus.com (英語)) などのさまざまなセキュリティ関連のニュースグループを監視すべきです。

技術者が基本的なセキュリティの教義、共通セキュリティの欠陥タイプ、基本的安全性の設計、またはセキュリティ テストについて何も知らない場合、実際には、安全なソフトウェアを作成できるチャンスはありません。ソフトウェア エンジニアは、概してセキュリティに対して充分注意を払っていないからです。エンジニアは、セキュリティのかなりの機能を認識しているかも知れませんが、安全な機能を構築し、配布するのに必要な事をより深く理解する必要があります。セキュリティという用語は、全く異なる 2 つのセキュリティの領域があるため、両方の意味を含めることは不適切です。セキュリティ機能は、ソフトウェアの動作方法、たとえば、Java や 共通言語ランタイム (CLR) サンドボックスの内部動作、または DES や RSA などの暗号化アルゴリズムの動作方法を調べます。すべて興味深く、有益なトピックですが、DES 暗号化アルゴリズムが 16 ラウンドの Feistel ネットワークであると知っていても、より安全なソフトウェアを作成する手助けにはなりません。DES の限界を知り、今日の脅威に対してキー サイズがあまりに小さすぎるという事実を認識することが有効であり、このような詳細情報こそが、安全な機能を構築する核心となります。

実際的な問題ですが、ほとんどの学校、大学、専門学校は、安全なソフトウェアの構築方法ではなく、セキュリティ機能を教えています。つまり、ファイアウォールの動作方法を知っているために安全なソフトウェアの構築方法を知っていると信じている多数のソフトウェア エンジニアが毎年量産されているのです。要するに、セキュリティ問題に関してエンジニアの背景や知識を特に尋ねない限り、雇用しているエンジニアが必ずしもソフトウェアにセキュリティの防御機能を構築する方法を理解していると考えることはできません。

オンラインおよびインストラクタによるセキュリティ教育の良い情報源として Microsoft E-Learning (www.microsoftelearning.com/japan/security) があります。開発者向けのセキュリティ ガイダンスは、マイクロソフトで私達が提供しているセキュリティの基本教材に由来しています。

図 2 に示したようなセキュリティに関する優良本のライブラリを作るべきです。

マイクロソフトの一部のグループが図書クラブを発足させました。そのクラブでは所定の本のある章を読み、内容について論議しています。より深い知識を備えるために、 Bugtraq (英語) などの共通セキュリティの馴染みの場から出される欠陥問題や設計問題などを検索しています。

セキュリティ担当者が、共通セキュリティのコードの欠陥 (バッファ オーバーフロー、クロスサイト スクリプティング、SQL インジェクション、整数演算、弱い暗号など)、安全な設計、脅威モデリングおよびセキュリティ テストなど、セキュリティ問題に関するプレゼンテーションを社内で行うとします。より深く、関連性のある議論を進めるために、ユーザー独自のコード内で欠陥を見つけ、他の開発者達にその欠陥を例として挙げるようにしてください。

エンジニアは、最終的には自分で勉強するか、または社員研修に出席して、少なくとも年 1 回は自分のスキル向上を目指して努力しなければなりません。エンジニアが落とし穴に落ちないよう、追跡調査すべきです。変化の激しい今日、セキュリティの全体像を完全に掌握することが非常に重要です。今日の共通不具合が、将来的に、セキュリティの脆弱性を露呈する可能性があります。

設計フェーズ

製品のセキュリティ設計に影響を与える最適時期は、製品のライフサイクルの初期段階です。この時期は従来、立案者、開発者、設計者が大部分の機能を設計するフェーズです。通常、目標とする機能の簡単な説明から設計を始め (機能の概要を短いフォームで示すことがある) 、次に、顧客から見た機能を示す機能仕様、さらに、機能の実装方法を概説した技術的な詳細情報を示す設計仕様を作成します。

小回りの利く開発方法を使用している場合、1 ページほどの短い概要を選ぶことができますが、必ずコンポーネントのセキュリティ面を入れなければなりません。機能仕様には、特定のデータや高度な機能にアクセスする場合にエンド ユーザーの認証を要求するなど、顧客に直接表示されるセキュリティ機能を記す必要があります。設計仕様は、セキュリティ機能の実装方法を示すと共に、すべての機能を安全な機能として確実に実装する必要があります。「セキュリティ」という言葉ではなく、「安全な」という言葉を使用していることに注意してください。安全な機能は、暗号化 API を確実に使用すること、可能な限りマネージ コードを使用すること、処理前にすべてのデータを厳密に確認すること、その他を考慮することなど、セキュリティに関するすべての機能がうまく設計されていることと定義されています。機能を設計する場合、設計プロセスの最終段階近くになって製品にセキュリティを導入しないように、注意深くセキュリティ問題を考えておくことが大切です。

すべての機能仕様や設計仕様には、文書のサイズとは関係なく、コンポーネントがどのようにセキュリティに影響するかを示した項を入れなければなりません。この項に何を追加すべきか知るには、RFC 3552 "Guidelines for Writing RFC Text on Security Considerations" (英語) を閲覧してください。

設計プロセスで重要なことは、アプリケーションまたはコンポーネントの攻撃対象領域を減少させる方法を理解することです。インターネットへ匿名でアクセス可能な開いた UDP ポートは、制限された IP アドレス セットにしかアクセスできない、いわゆる開いた TCP ポートと比べて、攻撃対象領域が広いことを意味しています。この課題についてここで詳しく述べるつもりはありません。代わりにMSDN Magazine 2004 年 11 月 の "Mitigate Security Risks by Minimizing the Code You Expose to Untrusted Users" (英語) に記載されている攻撃対象領域の減少に関する記事を参照するようお勧めします。コードの攻撃対象領域を減少させるためのクイック リファレンスを図 3 に示しています。

脅威モデリング (Thread Modeling)

脅威モデリングは、製品の設計プロセス中に完成しなければなりません。製品が保護しようとする資産 (コンピュータは言うに及ばず、クレジット カード番号などの顧客の個人情報)、製品により導入される脅威や脆弱性、脅威の軽減方法の詳細、を理解しない限り、安全な製品を構築することはできません。また、製品が配置される環境に存在する脅威や脆弱性、エンド ツー エンド リアルワールド ソリューションにおいて他の製品やシステムと相互作用し、インターフェイスとなるために発生する脅威や脆弱性を考慮することも重要です。このため、脅威モデルが所定の位置に設定されるまで、製品の設計フェーズが完了したと考えることはできません。脅威モデルは設計フェーズに不可欠のコンポーネントであり、製品の機能仕様と製品仕様両方を参照して、脆弱性と緩和策の両方を記述します。

ソフトウェアに対する脅威を理解することが、安全な製品の作成に重要な第一歩です。セキュリティ技術をアプリケーションに導入すると、アプリケーションが安全であると宣言する人が多数います。しかし、セキュリティの対応策を講じ、実社会の脅威を実際に解決するまで、コードは安全ではありません。これが脅威モデリングの目標です。30 分以内でこのプロセスに対する感覚を磨くために、私の同僚の Peter Torr が執筆したブログ Guerrilla Threat Modeling (英語) を読まれるようお勧めします。

開発フェーズ

開発フェーズ中、セキュリティ ツール、セキュリティ チェックリスト、および安全なコーディングのベスト プラクティスを実装して、安全な設計を実現する必要があります。安全な設計は、脆弱な実装により非常に簡単に不安定になることを覚えておいてください。

この説明を行う前に、非常に重要なことを指摘しておきたいと思います。セキュリティ ツールがソフトウェアを安全にするわけではありません。セキュリティ ツールは役立ちますが、ツール自体は攻撃に対して回復力のあるコードを作成しません。ツールを使用してポリシーを強化する知識豊富なワーク フォースを確保するための単なる置換コードはありません。Visual Studio 2005 Team System Developer's Edition の新しいバージョンには、非常に有益なセキュリティ ツールが装備されています。

PREfast  PREfast は C/C++ コードの分析ツールで、セキュリティ欠陥や不具合を見つけることができます。これはセキュリティ強化のための機能です。

Standard Annotation Language (SAL)  Visual Studio 2005 に追加されたすべてのツールのうち、SAL が最も興味ある技術です。検出が難しい不具合を見つけられるからです。以下のような関数を作成したと想像してください。

void *function(
    char *buffer, 
    DWORD cbBufferLength);

buffer と dwBufferLength は連結されていて、cbBufferLength の値は buffer の長さです。しかしコンパイラは、すべてがポインタで、32 ビットの符号なし整数であると認識しません。SAL を使用すると、この 2 つをリンクできます。この関数プロトタイプが含まれるヘッダは以下の通りです。

void *function(
    _in_bytecount(cbBufferLength) char *buffer, 
    DWORD cbBufferLength);

Visual Studio 2005 の出荷前に、SAL に使用された最後の構文が変更している可能性があることに注意してください。

FxCop  FxCop についてすでにご存知かもしれません。これは、マネージ コード内のセキュリティ欠陥を含め、欠陥を検出するツールです。FxCop は、www.gotdotnet.com からダウンロード可能ですが、Visual Studio 2005 のバージョンは完全に統合されており、注意を要する新たな問題もあります。

Application Verifier  AppVerifier は、稼動中のアプリケーションで作動するランタイム ツールです。ヒープベースのバッファ オーバーランを含め、ランタイム時のメモリ関連の問題をトラップするのに使用できます。

他のツールおよびマイクロソフトの要件は以下の通りです。

  • すべてのアンマネージ C/C++ コードは /GS スタック オーバーラン検出機能を使用してコンパイルしなければならない。
  • すべてのアンマネージ C/C++ コードは /SafeSEH オプションを使用してリンクしなければならない。
  • すべての RPC コードは MIDL /robust フラグを使用してコンパイルしなければならない。
  • FxCop および PREfast によりフラグを立てられたセキュリティ問題を修正しなければならない。
  • 図 4 に示した関数は、新しいコードに禁止されている。そのうち、レガシー コードで削除されるはずである。

Strsafe 文字列の置換コードについては、Strsafe.h: Safer String Handling in C に記載しています。安全な C ライブラリは、Visual Studio 2005 に内蔵された新規 C ランタイム ライブラリ置換です。SAFE! : Visual Studio 2005 Safe C および C++ ライブラリでコードへの攻撃を撃退する でもこれに関する記事を読むことができます。

セキュリティ テスト

セキュリティの欠陥を検出する非常に便利な技術が "ファジング (fuzzing)" で、有効データを取り出し、そのデータをモーフィングし、そのデータを消費するアプリケーションを観察することを意味します。最も簡単なフォームとしては、アプリケーションが消費する有効ファイルのライブラリを構築し、ツールを使用して系統立ててファイルを破壊し、アプリケーションにそのファイルを再生、レンダリングさせます。Application Verifier にて、より多くのエラーを検出できるヒープ チェック機能を使用してアプリケーションを実行します。データのモーフィング例は以下の通りです。

  • ファイルの任意のバイトを交換する
  • ファイル内の任意の位置に、任意のサイズの一連のバイトを記述する
  • 既知の整数を見つけ符号を変更するか、または非常に大きい値または非常に小さい値を指定する
  • ASCII または Unicode 文字を見つけ、終了の NULL 文字を非 NULL 文字に設定する

Michael Sutton および Adam Greene は、ファジングに関する Blackhat USA 2005 のセッションに興味を示しています。これについては、 The Art of File Format Fuzzing (英語) に説明があります。Ejovi Nuwere および Mikko Varpiola も、VoIP ネットワーキング プロトコルのファジングに関するプレゼンテーションに関心を抱いています。 The Art of SIP Fuzzing and Vulnerabilities Found in VoIP (英語) から詳細情報を入手できます。

セキュリティ プッシュ(Security Push) の開始

セキュリティ プッシュは、チーム全体の脅威モデルの更新、コード レビュー、テストおよび文書のスクラブを中心に扱っています。プッシュとは、セキュリティの統制が取れていないプロセスを早急に修正することではなく、むしろ、協力しながらセキュリティ アーキテクチャ文書の情報の妥当性を確認し、開発プロセス中に発生した可能性のある変更を見つけ、残りのセキュリティの脆弱性を発見すると、それを特定して改善することです。セキュリティ プッシュだけを使用してソフトウェアのセキュリティを守ることは不可能です。

セキュリティ プッシュに必要な時間数を決める簡単な方法はありません。今まですべてのプッシュがコードの量によって制御されてきたので、プッシュの期間は結局はセキュリティの検証に必要なコード数によって決まります。あまりに多くのコード レビューを短期間に集中して実行しようとすると、コード レビューの品質低下に繋がるので、コードがかなり安定すると、開発プロセス中にセキュリティ コード レビューを実施するよう、強く求められます。

経験から言って、インターネットへの露出、機密情報や個人情報の処理、最優先順位のコードとしてのマークづけなど、発見的教授法 (heuristics) を使用し、必要不可欠なコードを決めることが大切です。そのコードは、プッシュ中にレビューされなければなりません。コードがレビューされるまでは、プッシュを完了できません。すべてのコード ファイルに名前を割り当て、コードに名前と優先順位を割り当ててから、プッシュを実行してください。

最終的なセキュリティ レビュー (Final Security Reviews)

プロジェクトの最終段階近くになると、セキュリティの観点から見て、ソフトウェアの出荷準備が整っただろうかという、非常に重要な質問に答えなければなりません。最終的なセキュリティ レビュー (FSR) が質問の答えを導き出します。製品開発チームの助けを借りて (製品開発チームだけではありませんが)、中央のセキュリティ チームが FSR を実施します。通常は、ソフトウェア完成前に、以下を行います。

  • セキュリティ チームが集中的に行う作業を決定するのに役立つ、質問事項を作成します。以下の様な質問を含めます。
  • スクリプティングに安全な ActiveX コントロールを持っていますか。

不明確と思われたプロトコルはすべてを記述してください。

  • コンポーネントが非認証接続をしていますか。
  • コンポーネントが UDP を使用していますか。
  • コンポーネントが ISAPI アプリケーションまたはフィルタを使用していますか。
  • いずれかのコードがシステム コンテキストで実行されていますか。 実行されている場合、その理由は何ですか。
  • セットアップ コードで ACL を設定しましたか。
  • "修正されない"と思われる不具合をレビューし、セキュリティの欠陥を誤ってマークしていないか確認します。
  • 製品の他のバージョンや競合相手の製品からセキュリティ欠陥を分析し、問題のすべてを処理したか確認します。共通な質問の 1 つは、"どのように広範な種類のセキュリティ問題を軽減しましたか" です。
  • 高リスクのコンポーネントのペネトレーション テスト (サードパーティ製) を実行します。

FSR プロセスの最後で、発見した事項を書き留め、ソフトウェアをリリースするか、再作業するか決断します。

セキュリティの対応

このプロセスの主要部分は 2 つあります。1 つは、セキュリティ欠陥に対応し、コード内でセキュリティの問題を検出した人と作業することです。もう 1 つの側面は、これらの誤りから学習することです。マイクロソフトには、欠陥の原因分析をする専門スタッフがいます。これらの文書は、SDL の後続製品に反映するために使用され、各事後分析文書には次の項目があります。

  • ファイル名とバージョン
  • 設計の問題でしたか。
  • コーディングの問題でしたか。
  • コーディング バグの場合、ソース コードの相違です。
  • 不具合は製品の他のバージョンに影響しますか。影響する場合、その理由は何ですか。影響しない場合は何故影響しないのですか。(両方とも非常に有効な質問です。)
  • この欠陥をどのテストで検出しましたか。
  • この欠陥をどのツールで検出しましたか。
  • 問題を検出するために、教育、ツールまたはプロセスを変更する必要がありますか。

回答は SDL の変更に使用されます。マイクロソフトの SDL は 1 月 1 日、7 月 1 日の年 2 回更新されます。

SDL が作動しますか

"SDL が作動しますか。セキュリティ開発ライフサイクル技術を採用すると、結果的に安全なソフトウェアになりますか。" という大きな問題があります。回答は勿論「はい」です。SDL に従った場合、セキュリティの欠陥数が約 50 ~ 60% 減少しています。事実、SDL を実施した各製品のセキュリティ欠陥はわずかです。確実に、製品価値を追い求めています。


Michael Howard は、マイクロソフトのシニア セキュリティ プログラム マネージャであり、安全なプロセス改善とベスト プラクティスを中心に日々努力しています。『19 Deadly Sins of Software Security』 (McGraw-Hill Osborne, 2005) および 『Processes to Produce Secure Software』 (Dept. of Homeland Security National Cyber Security Division) を共同執筆しました。


 この記事は、 MSDN マガジン - 2005 年 11 月号からの翻訳です。 .