安全なコードを作成するためのガイドライン
以下のガイドラインでは、安全なコードを作成するためのさまざまなテクニックを紹介しています。
必須
コード分析ツールを使用する。
Visual Studio Premium には、コード中に存在するセキュリティ バグを高い確率で検出できるコード分析ツールが付属しています。 これらのツールを使用することで、バグを少ない労力で、より効率よく検出できます。 詳細については、次のトピックを参照してください。
セキュリティ レビューを実施する。
セキュリティ レビューの目的には、既にリリースされた製品のセキュリティを更新プログラムを提供して強化することと、最大限のセキュリティが確保されるまでは新しい製品をリリースしないようにすることとが含まれます。
無作為にコードをレビューすることは避けてください。 セキュリティ レビューを行う前に、まず、脅威のモデリングを慎重に行い、十分な準備作業を行います。 これを怠ると、チーム全体の貴重な時間が無駄になってしまいます。 コードに優先順位を付け、最も重点的にセキュリティ レビューを行う必要のあるコードおよび解決を要するセキュリティ バグを見極める必要があります。
セキュリティ レビューで何を見つけたいかを明確にしてください。 見つけようとする問題がわかっていれば、それらを見つけることはさほど難しいことではありません。 1 つの領域で多数のセキュリティ バグが見つかっている場合、すべてのハンドラーを調べてください。 修正の必要がある、アーキテクチャ上の問題が生じている可能性があります。 セキュリティ バグがまったく見つからないということは通常はありません。多くの場合、セキュリティ レビューが正しく実行されなかったことが原因です。
セキュリティ レビューは、各マイルストーンの検証作業、および、マネージメントにより設定された、より大規模な製品戦略の一部と考えてください。
セキュリティ コード レビューのチェックリストを使用する。
ソフトウェア開発チームでの役割に関係なく、チェックリストを使用するようにしてください。デザインおよびコードの最低要件を確実に満たすための有効な手段となります。
すべてのユーザー入力を検証する。
直接と間接を問わずユーザーからの入力を受け取るアプリケーションを作成する場合は、入力された情報を使用する前に、その内容を検証する必要があります。 悪意を持ったユーザーが、無効なデータを入力として渡すことによってアプリケーションの正常動作を妨げようとする場合があります。 原則的に、あらゆるユーザー入力は、その内容が検証されるまでは不正なデータであると考えてください。
正規表現を使ってユーザー入力を検証する場合は十分な注意が必要です。 電子メール アドレスのような複雑な式では、確実に検証しているつもりでも、実際にはそうでない場合があります。 すべての正規表現を他のチーム メンバーに確認してもらってください。
エクスポートされたパブリックなアプリケーション プログラミング インターフェイス (API) のすべてのパラメーターを厳密に検証する。
エクスポートされたパブリックな API のすべてのパラメーターが有効であるかどうかを確認してください。 これには、一貫しているように見えても、値の許容範囲を超えているような入力が含まれます (バッファー サイズが大きすぎるなど)。 エクスポートされた API のパラメーター チェックに、アサートは使用できません。リリース ビルドではアサートが除去されるためです。
Windows の暗号化 API を使用する。
暗号化ソフトウェアを独自に作成するのではなく、既に入手可能な Microsoft の暗号化 API を使用します。 Microsoft の暗号化 API を使用することで、開発者はアプリケーションの開発作業だけに専念できます。 ただし、暗号化で完全に解決できる問題はほんの一部であり、本来想定された用途とは異なる目的で利用されることがあります。 詳細については、MSDN ライブラリの「Cryptography Reference (暗号リファレンス)」を参照してください。
避けるべきこと
バッファー オーバーラン。
静的バッファー オーバーランは、スタック上に宣言されたバッファーが、そのサイズを超えるデータをコピーすることによって上書きされた場合に発生します。 スタック上に宣言される変数は、関数呼び出し元のリターン アドレスと隣り合う位置に格納されます。 バッファー オーバーランは、ヒープ上でも発生するため、セキュリティ上きわめて深刻な問題となります。 最も典型的な原因としては、strcpy などの関数に対し、ユーザー入力を検証しないまま渡すことが挙げられます。この場合、関数のリターン アドレスが、攻撃者により指定されたアドレスで上書きされるおそれがあります。 バッファー オーバーランを防ぐことは、多くの場合、堅牢なアプリケーションを作成できるかどうかを左右します。
外部入力をアサートでチェックする。
アサートは、リテール ビルドにはコンパイルされません。 アサートを使用して、外部入力を検証することは避けてください。 エクスポートされる関数およびメソッドのパラメーター、ユーザー入力、ファイル データ、ソケット データはすべて、有効性を慎重に検証し、違反が見られた場合は拒否するようにします。
ユーザー ID とパスワードのペアをハードコーディングする。
パスワードをハードコーディングしないでください。 ビルトインのユーザー アカウントが作成された場合は、各アカウントに強力なパスワードを設定することを管理者に促すよう、インストーラーを修正してください。 こうすることで、顧客が利用するシステムのセキュリティを製品レベルで確保できます。
セキュリティ上の問題解決を暗号化だけに依存する。
ただし、暗号化で完全に解決できる問題はほんの一部であり、本来想定された用途とは異なる目的で利用されることがあります。
標準ファイル パスや標準 URL を使用する。
ファイルや URL の場所が問題となるような状況は避けてください。 標準ファイル名に基づく規則は使用せずに、ファイル システムの ACL を使用します。
推奨
過去に遭遇したセキュリティ上の問題をすべてレビューする。
過去に犯したセキュリティ上のミスを十分に認識することが大切です。 コードの作成には、同じパターンの繰り返しが多く用いられます。 したがって、ある開発者が、どこかに、バグの存在するコードを記述した場合、他の開発者も、同じバグを別の場所で犯している可能性があります。
すべてのエラー パスをレビューする。
エラー パス上のコードが十分にテストされず、一部のオブジェクト (ロックやメモリ割り当てなど) が破棄されずに残っているケースがよくあります。 これらのパスを十分にレビューし、必要に応じてフォールト インジェクション テストを作成してコードをテストするようにしてください。 詳細については、MSDN ライブラリで「セキュリティ保護された Web アプリケーションの設計ガイドライン」の「入力検証」セクションおよび「セキュリティのためのアーキテクチャと設計レビュー」の「入力検証」セクションを参照してください。
できれば避けること
アプリケーションの実行に管理者権限を使用する。
アプリケーションの実行には、処理に必要な最小限の権限だけを与えるようにしてください。 万一、セキュリティ上の脆弱性が悪意を持つユーザーによって発見され、アプリケーションのプロセスに悪質なコードが挿入された場合、そのコードがホスト プロセスと同じ権限で実行されてしまいます。 ホスト プロセスが管理者として実行されていた場合、悪質なコードが管理者権限で実行されることになります。 詳細については、MSDN ライブラリの「管理者権限を持たずに Visual Studio .NET を使用してソフトウェアを開発する」を参照してください。