安全なコードを作成するためのガイドライン

更新 : 2007 年 11 月

以下のガイドラインでは、安全なコードを作成するためのさまざまなテクニックを紹介しています。

必ず行うこと

  • コード分析ツールを使用する。

    Visual Studio Team System Development Edition には、コード中に存在するセキュリティ バグを高い確率で検出できるコード分析ツールが付属しています。これらのツールを使用することで、バグを少ない労力で、より効率よく検出できます。詳細については、「C/C++ コード障害の検出と修正」および「マネージ コード障害の検出と修正」を参照してください。

  • セキュリティ レビューを実施する。

    セキュリティ レビューの目的には、既に出荷された製品のセキュリティを更新プログラムやセキュリティ修正プログラムを通じて強化することと、最大限のセキュリティが確保されるまでは新しい製品を出荷しないようにすることとが含まれます。

    無作為にコードをレビューすることは避けてください。セキュリティ レビューを行う前に、まず、脅威のモデリングを慎重に行い、十分な準備作業を行います。これを怠ると、チーム全体の貴重な時間が無駄になってしまいます。コードに優先順位を付け、最も重点的にセキュリティ レビューを行う必要のあるコードおよび解決を要するセキュリティ バグを見極める必要があります。

    セキュリティ レビューで何を見つけたいかを明確にしてください。見つけようとする問題がわかっていれば、それらを見つけることはさほど難しいことではありません。ある特定の領域にセキュリティ バグが集中していた場合はさらに注意深く観察する必要があります。アーキテクチャの修正を要する問題が関係している可能性があります。セキュリティ バグがまったく見つからないということは通常はありません。多くの場合、セキュリティ レビューが正しく実行されなかったことが原因です。

    セキュリティ レビューは、各マイルストーンの検証作業、および、マネージメントにより設定された、より大規模な製品戦略の一部と考えてください。

  • セキュリティ コード レビューのチェックリストを使用する。

    ソフトウェア開発チームでの役割に関係なく、チェックリストを使用するようにしてください。デザインおよびコードの最低要件を確実に満たすための有効な手段となります。

  • すべてのユーザー入力を検証する。

    直接と間接を問わずユーザーからの入力を受け取るアプリケーションを作成する場合は、入力された情報を使用する前に、その内容を検証する必要があります。悪意を持ったユーザーが、無効なデータを入力として渡すことによってアプリケーションの正常動作を妨げようとする場合があります。原則的に、あらゆるユーザー入力は、その内容が検証されるまでは不正なデータであると考えてください。

    正規表現を使ってユーザー入力を検証する場合は十分な注意が必要です。電子メール アドレスのような複雑な式では、確実に検証しているつもりでも、実際にはそうでない場合があります。すべての正規表現を他のチーム メンバに確認してもらってください。

  • エクスポートされたアプリケーション プログラミング インターフェイス (API) のすべてのパラメータを厳密に検証する。

    エクスポートされた API のすべてのパラメータが有効であるかどうかを確認してください。これには、一貫しているように見えても、値の許容範囲を超えているような入力が含まれます (バッファ サイズの異常など)。エクスポートされた API のパラメータ チェックに、アサートは使用できません。リリース ビルドではアサートが除去されるためです。

  • Windows の暗号化 API を使用する。

    暗号化ソフトウェアを独自に作成するのではなく、既に入手可能な Microsoft の暗号化 API を使用します。Microsoft の暗号化 API を使用することで、開発者はアプリケーションの開発作業だけに専念できます。ただし、暗号化で完全に解決できる問題はほんの一部であり、本来想定された用途とは異なる目的で利用されることがあります。詳細については、MSDN ライブラリの 「暗号化の概要」を参照してください。

避けるべきこと

  • バッファ オーバーラン。

    静的バッファ オーバーランは、スタック上に宣言されたバッファが、そのサイズを超えるデータをコピーすることによって上書きされた場合に発生します。スタック上に宣言される変数は、関数呼び出し元のリターン アドレスと隣り合う位置に格納されます。バッファ オーバーランは、ヒープ上でも発生するため、セキュリティ上きわめて深刻な問題となります。最も典型的な原因としては、strcpy などの関数に対し、ユーザー入力を検証しないまま渡すことが挙げられます。この場合、関数のリターン アドレスが、攻撃者により指定されたアドレスで上書きされてしまう恐れがあります。バッファ オーバーランを防ぐことは、多くの場合、堅牢なアプリケーションを作成できるかどうかを左右します。

  • 外部入力をアサートでチェックする。

    アサートは、リテール ビルドにはコンパイルされません。アサートを使用して、外部入力を検証することは避けてください。エクスポートされる関数およびメソッドのパラメータ、ユーザー入力、ファイル データ、ソケット データはすべて、有効性を慎重に検証し、違反が見られた場合は拒否するようにします。

  • ユーザー ID とパスワードのペアをハードコーディングする。

    パスワードをハードコーディングしないでください。ビルトインのユーザー アカウントが作成された場合は、各アカウントに強力なパスワードを設定することを管理者に促すよう、インストーラを修正してください。こうすることで、顧客が利用するシステムのセキュリティを製品レベルで確保できます。

  • セキュリティ上の問題解決を暗号化だけに依存する。

    ただし、暗号化で完全に解決できる問題はほんの一部であり、本来想定された用途とは異なる目的で利用されることがあります。

  • 標準ファイル パスや標準 URL を使用する。

    ファイルや URL の場所が問題となるような状況は避けてください。標準ファイル名に基づく規則は使用せずに、ファイル システムの ACL を使用します。

お勧めすること

  • 過去に遭遇したセキュリティ上の問題をすべてレビューする。

    過去に犯したセキュリティ上のミスを十分に認識することが大切です。コードの作成には、同じパターンの繰り返しが多く用いられます。したがって、ある開発者が、どこかに、バグの存在するコードを記述してしまった場合、他の開発者も、同じバグを別の場所で犯している可能性があります。

  • すべてのエラー パスをレビューする。

    エラー パス上のコードが十分にテストされず、一部のオブジェクト (ロックやメモリ割り当てなど) が破棄されずに残ってしまっているケースがよくあります。これらのパスを十分にレビューし、必要に応じてフォールト インジェクション テストを作成してコードをテストするようにしてください。

できれば避けること

  • アプリケーションの実行に管理者権限を使用する。

    アプリケーションの実行には、処理に必要な最小限の権限だけを与えるようにしてください。万一、セキュリティ上の脆弱性が悪意を持つユーザーによって発見され、アプリケーションのプロセスに悪質なコードが挿入された場合、そのコードがホスト プロセスと同じ権限で実行されてしまいます。ホスト プロセスが管理者として実行されていた場合、悪質なコードが管理者権限で実行されることになります。詳細については、MSDN ライブラリの「Developing Secure Applications」を参照してください。

参照

その他の技術情報

脅威のモデリング