開発ライフサイクルをセキュリティで保護するための推奨事項

この Azure Well-Architected Framework セキュリティ チェックリストの推奨事項に適用されます。

SE:02 セキュリティで保護された、主に自動化された監査可能なソフトウェア サプライ チェーンを使用して、安全な開発ライフサイクルを維持します。 脅威モデリングを使用してセキュリティを破る実装から保護することで、セキュリティで保護された設計を組み込みます。

関連ガイド: 脅威分析

このガイドでは、開発サイクル全体でセキュリティのベスト プラクティスを適用して 、コード、開発環境、およびソフトウェアサプライ チェーンを強化するための推奨事項 について説明します。 このガイダンスを理解するには、DevSecOps に関する知識が必要です。

セキュリティ サイクルの図。

DevSecOps は、次の方法でセキュリティを DevOps プロセスに統合します。

  • セキュリティ テストと検証の自動化。

  • コードおよびコードとしてのインフラストラクチャ (IaC) をスキャンして脆弱性を検出するためのセキュリティ パイプラインなどのツールを実装する。

ワークロードの中核となるのは、ビジネス ロジックを実装するアプリケーション コードです。 コードとコード開発プロセスは、機密性、整合性、可用性を確保するために 、セキュリティ上の欠陥がないように する必要があります。

ID やネットワークなどの手段に関するコントロールを使用してインフラストラクチャ プレーンだけをセキュリティで保護するだけでは十分ではありません。 コードの不適切な実装や侵害されたコード ブロックを防ぎ 、全体的なセキュリティ体制を強化します。 使用プレーン (アプリケーション コード) も強化する必要があります。 セキュリティを開発ライフサイクルに統合するプロセスは、基本的に強化プロセスです。 リソースのセキュリティ強化と同様に、コード開発の締め付けもコンテキストに依存しません。 アプリケーションの機能要件ではなく、セキュリティの強化に重点を置きます。 セキュリティ強化に関連する情報については、「 リソースのセキュリティ強化に関する推奨事項」を参照してください。

定義

期間 定義
セキュリティ開発ライフサイクル (SDL) セキュリティの保証とコンプライアンスの要件をサポートする Microsoft によって提供される一連のプラクティス。
ソフトウェア開発ライフサイクル (SDLC) ソフトウェア システムを開発するためのマルチステージで体系的なプロセス。

主要な設計戦略

セキュリティ対策は、次のことを保証するために、既存のソフトウェア開発ライフサイクル (SDLC) に複数のポイントで統合する必要があります。

  • 設計の選択によってセキュリティギャップが発生することはありません。

  • アプリケーション コードと構成では、悪用可能な実装と不適切なコーディングプラクティスにより、脆弱性は生じません。

  • サプライ チェーンを介して取得されたソフトウェアでは、セキュリティ上の脅威は発生しません。

  • アプリケーション コード、ビルド、展開のプロセスは改ざんされません。

  • インシデントによって明らかにされた脆弱性は軽減されます。

  • 未使用の資産は適切に使用停止されます。

  • コンプライアンス要件は侵害されたり減らされたりすることはありません。

  • 監査ログは、開発者環境に実装されます。

以下のセクションでは、SDLC の一般的に実施されるフェーズのセキュリティ戦略について説明します。

要件フェーズ

要件フェーズの目的は、アプリケーションまたはアプリケーション の新機能の機能要件と非機能要件を収集して分析 することです。 このフェーズは、アプリケーションの目的に合わせて調整されたガードレールの作成を容易にするため、重要です。 アプリケーションのデータと整合性を保護することは、開発ライフサイクルのすべてのフェーズを通じてコア要件である必要があります。

たとえば、ユーザーがデータをアップロードおよび操作できるようにする重要なユーザー フローをサポートする必要があるアプリケーションを考えてみましょう。 セキュリティ設計の選択肢では、ユーザー ID の認証と承認、データに対する許可されたアクションの許可、SQL インジェクションの防止など、アプリケーションとのユーザーの対話に関する保証をカバーする必要があります。 同様に、可用性、スケーラビリティ、保守容易性などの機能以外の要件もカバーします。 セキュリティの選択には、セグメント化の境界、ファイアウォールのイングレスとエグレス、およびその他の横断的なセキュリティ上の問題が含まれる必要があります。

これらの決定はすべて、アプリケーションのセキュリティ体制を適切に定義する必要があります。 合意された仕様でセキュリティ要件を文書化 し、バックログに反映します。 投資がビジネス利害関係者によって承認されていない場合に、セキュリティ投資と、ビジネスが引き受ける可能性があるトレードオフとリスクを明示的に明記する必要があります。 たとえば、Azure Front Door や Azure Application Gateway など、アプリケーションの前で Web アプリケーション ファイアウォール (WAF) を使用する必要性を文書化できます。 ビジネス利害関係者が WAF を実行する追加コストを受け入れる準備ができていない場合は、アプリケーション層攻撃がアプリケーションに向けられる可能性があるリスクを受け入れる必要があります。

セキュリティ要件の収集は、このフェーズの重要な部分です。 この作業がなければ、設計と実装のフェーズは、控えめな選択に基づいて行われ、セキュリティギャップにつながる可能性があります。 セキュリティに対応するために、後で実装を変更することが必要になる場合があります。これはコストがかかる可能性があります。

設計フェーズ

このフェーズでは、 セキュリティ要件は技術的な要件に変換されます。 技術仕様では、実装時のあいまいさを防ぐために、すべての設計上の決定事項を文書化します。 一般的なタスクを次に示します。

システム アーキテクチャのセキュリティ ディメンションを定義する

セキュリティ コントロールを使用してアーキテクチャをオーバーレイします。 たとえば、 セグメント化戦略に従って分離境界で実用的なコントロール、アプリケーションのコンポーネントに必要な ID の種類、使用する暗号化方法の種類などです。 アーキテクチャの例については、 ID とアクセスの管理 に関する記事とネットワークに関する記事の「例」セクションの図 参照してください。

プラットフォーム提供のアフォーダンスを評価する

自分 とクラウド プロバイダーの間の責任の分割を理解することが重要です。 たとえば、Azure ネイティブ セキュリティ コントロールとの重複を避けます。 セキュリティカバレッジが向上し、開発リソースをアプリケーションのニーズに再割り当てできるようになります。

たとえば、設計でイングレス時に Web アプリケーション ファイアウォールが必要な場合は、その責任を Application Gateway や Azure Front Door などのロード バランサーにオフロードできます。 アプリケーションでカスタム コードとして機能をレプリケートしないようにします。

信頼できるフレームワーク、ライブラリ、サプライ チェーン ソフトウェアのみを選択します。 設計では、セキュリティで保護されたバージョン管理も指定する必要があります。 アプリケーションの依存関係は、信頼できる関係者から提供する必要があります。 サードパーティベンダーは、セキュリティ要件を満たし 、責任ある開示計画を共有できる必要があります。 必要なアクションを実行できるように、セキュリティ インシデントを迅速に報告する必要があります。 また、organizationによって特定のライブラリが禁止されている場合もあります。 たとえば、ソフトウェアは脆弱性から保護されていても、ライセンスの制限により許可されていない可能性があります。

このガイダンスの後にソフトウェアへのすべての共同作成者が確実に表示されるようにするには、 承認または未承認のフレームワーク、ライブラリ、ベンダーの一覧を維持します。 可能な場合は、一覧をサポートするために、開発パイプラインにガードレールを配置します。 可能な限り、 脆弱性の依存関係をスキャンするためのツールの使用を自動化 します。

アプリケーション コードで実装する必要があるセキュリティ設計パターンを決定します。

パターンは、セグメント化と分離、強力な承認、統一されたアプリケーション セキュリティ、最新のプロトコルなどのセキュリティ上の問題をサポートできます。 検疫パターンなどの一部の運用パターンは、セキュリティの脆弱性を引き起こす可能性があるソフトウェアの使用を検証してブロックするのに役立ちます。

詳細については、「セキュリティを サポートするクラウド設計パターン」を参照してください。

アプリケーション シークレットを安全に格納する

アプリケーションで使用するアプリケーション シークレットと事前共有キーの使用を安全に実装します。 資格情報とアプリケーション シークレットをソース コード ツリーに格納しないでください。 Azure Key Vault などの外部リソースを使用して、ソース コードが潜在的な攻撃者が利用できるようになった場合に、それ以上のアクセスを取得できないようにします。 一般に、シークレットを回避する方法を見つけます。 可能であれば、マネージド ID を使用することは、その目標を達成する 1 つの方法です。 詳細については、「 アプリケーション シークレットを管理するための推奨事項」を参照してください。

テスト計画を定義する

セキュリティ要件の明確なテスト ケースを定義します。 パイプラインでこれらのテストを自動化できるかどうかを評価します。 チームに手動テストのプロセスがある場合は、それらのテストのセキュリティ要件を含めます。

注意

このフェーズで脅威モデリングを実行します。 脅威モデリングでは、設計の選択がセキュリティ要件と一致していることを確認し、軽減する必要があるギャップを公開できます。 ワークロードが機密性の高いデータを処理する場合は、脅威モデリングの実施に役立つセキュリティ専門家に投資します。

最初の脅威モデリングの演習は、ソフトウェアのアーキテクチャと高度な設計が定義されている設計フェーズ中に発生する必要があります。 このフェーズでは、システムの構造に組み込まれる前に、潜在的なセキュリティの問題を特定するのに役立ちます。 ただし、この演習は 1 回限りのアクティビティではありません。 これは、ソフトウェアの進化を通じて継続する必要がある継続的なプロセスです。

詳細については、「 脅威分析の推奨事項」を参照してください。

開発とテストのフェーズ

このフェーズでは、コード、ビルド、デプロイ パイプラインの セキュリティ上の欠陥 や改ざんを防ぐことが目標です。

セキュリティで保護されたコード プラクティスで十分なトレーニングを受ける

開発チームは 、セキュリティで保護されたコーディング プラクティスに関する正式で専門的なトレーニングを受ける必要があります。 たとえば、Web および API 開発者は、クロスサイト スクリプティング攻撃から保護するための特定のトレーニングが必要な場合があり、バックエンド開発者は、SQL インジェクション攻撃などのデータベース レベルの攻撃を回避するための詳細なトレーニングの恩恵を受けることができます。

開発者は、運用ソース コードにアクセスする前に、このトレーニングを完了する必要があります。

また、継続的な学習を促進するために、内部ピア コード レビューを実行する必要もあります。

セキュリティ テスト ツールを使用する

脅威モデリングを実行して、アプリケーションのアーキテクチャのセキュリティを評価します。

静的アプリケーション セキュリティ テスト (SAST) を使用して、コードの脆弱性を分析します。 この手法を開発環境に統合して、リアルタイムで脆弱性を検出します。

実行時に 動的アプリケーション セキュリティ テスト (DAST) を使用します。 このツール チェーンは、セキュリティ ドメイン内のエラーをチェックし、一連の攻撃をシミュレートして、アプリケーションのセキュリティ回復性をテストできます。 可能であれば、このツールをビルド パイプラインに統合します。

セキュリティで保護されたコーディングプラクティスについては、業界標準に従ってください。 詳細については、この記事の 「コミュニティ リソース 」セクションを参照してください。

リンターとコード アナライザーを使用して、資格情報がソース コード リポジトリにプッシュされないようにします。 たとえば、.NET Compiler Platform (Roslyn) アナライザーは、アプリケーション コードを検査します。

ビルド プロセス中に、 パイプライン アドオンを使用して、ソース コード内の資格情報をキャッチします。 継続的インテグレーション プロセスの一環として、サードパーティのライブラリやフレームワーク コンポーネントなど、すべての依存関係をスキャンします。 ツールによってフラグが設定された、脆弱性のあるコンポーネントを調査します。 このタスクを、コード チャーン、テスト結果、カバレッジを検査する他のコード スキャン タスクと組み合わせます。

テストの組み合わせを使用します。 一般的なセキュリティ テストの詳細については、「 セキュリティ テストの推奨事項」を参照してください。

十分なコードを記述する

コードのフットプリントを減らすと、セキュリティ上の欠陥の可能性も減ります。 既に使用されており、コードを複製する代わりにセキュリティ検証を行っているコードとライブラリを再利用 します。

Azure の機能を利用することは、不要なコードを防ぐもう 1 つの方法です。 1 つの方法は、マネージド サービスを使用することです。 詳細については、「サービスとしてのプラットフォーム (PaaS) オプションを使用する」参照してください。

既定では、deny-all アプローチを使用してコードを記述します。 アクセスが必要なエンティティに対してのみ許可リストを作成します。 たとえば、特権操作を許可するかどうかを判断する必要があるコードがある場合は、 拒否 の結果が既定のケースであり、 許可 結果がコードによって明示的に許可されている場合にのみ発生するように記述する必要があります。

開発環境を保護する

開発者ワークステーションは、露出を 防ぐために、強力なネットワークと ID コントロールで保護する必要があります。 セキュリティ更新プログラムが慎重に適用されていることを確認します。

ビルド エージェントは高い特権を持ち、ビルド サーバーとコードにアクセスできます。 これらは、ワークロード コンポーネントと同じ厳しさで保護する必要があります。 つまり、 ビルド エージェントへのアクセスは認証および承認される必要があり、ファイアウォール制御を使用してネットワーク セグメント化する必要があり、脆弱性スキャンの対象になる必要があります。 Microsoft でホストされるビルド エージェントは、セルフホステッド ビルド エージェントよりも優先する必要があります。 Microsoft ホステッド エージェントには、パイプラインの実行ごとに仮想マシンクリーンなどの利点があります。

カスタム ビルド エージェントは、管理の複雑さを増加させ、攻撃ベクトルになる可能性があります。 ビルド マシンの資格情報は安全に格納する必要があり、ファイル システムから一時的なビルド成果物を定期的に削除する必要があります。 Azure DevOps との通信のプル モデルを使用しているため、ビルド エージェントからの送信トラフィックのみを許可することで、ネットワーク分離を実現できます。

ソース コード リポジトリも保護する必要があります 。 必要に応じてコード リポジトリへのアクセス権を付与し、攻撃を回避するために脆弱性の露出を可能な限り減らします。 セキュリティの脆弱性についてコードを確認するための徹底的なプロセスを用意します。 その目的でセキュリティ グループを使用し、ビジネス上の正当な理由に基づく承認プロセスを実装します。

セキュリティで保護されたコードのデプロイ

コードをセキュリティで保護するだけでは十分ではありません。 悪用可能なパイプラインで実行される場合、すべてのセキュリティ作業は無駄で不完全です。 また、悪意のあるアクターがパイプラインで悪意のあるコードを実行しないようにするため、ビルド環境とリリース環境も保護する必要があります

アプリケーションに統合されているすべてのコンポーネントの最新のインベントリを維持する

アプリケーションに統合されたすべての新しいコンポーネントによって、攻撃対象領域が増加します。 新しいコンポーネントが追加または更新されたときに適切なアカウンタビリティとアラートを確実に行うには、これらのコンポーネントのインベントリが必要です。 ビルド環境の外部に保存します。 定期的に、マニフェストがビルド プロセスの内容と一致することをチェックします。 これにより、バック ドアやその他のマルウェアを含む新しいコンポーネントが予期せず追加されないようにすることができます。

パイプラインのタスク

  • Azure Marketplaceなど、信頼できるソースからパイプライン内のタスクをプルします。 パイプライン ベンダーによって作成されたタスクを実行します。 GitHub タスクまたはGitHub Actionsをお勧めします。 GitHub ワークフローを使用する場合は、Microsoft が作成したタスクを優先します。 また、タスクはパイプラインのセキュリティ コンテキストで実行されるため、タスクを検証します。

  • パイプライン シークレット。 パイプライン内で実行されるデプロイ資産は、そのパイプライン内のすべてのシークレットにアクセスできます。 不要な露出を回避するために、パイプラインのさまざまなステージに適切なセグメント化を設定します。 パイプラインに組み込まれているシークレット ストアを使用します。 状況によってはシークレットの使用を避けることができることに注意してください。 ワークロード ID (パイプライン認証用) とマネージド ID (サービス間認証用) の使用方法について説明します。

異なる環境を分離する

異なる環境で使用されるデータは、個別に保持する必要があります。 低い環境では運用データを使用しないでください 。これらの環境には、運用環境に厳密なセキュリティ制御が設定されていない可能性があるためです。 非運用アプリケーションから運用データベースへの接続は避け、非運用コンポーネントを運用ネットワークに接続しないようにします。

プログレッシブ 露出

選択した条件に基づいて ユーザーのサブセットに機能をリリースするには、 段階的な公開を使用します。 問題がある場合、それらのユーザーへの影響は最小限に抑えられます。 このアプローチは、サーフェス領域が減少するため、一般的なリスク軽減戦略です。 機能が成熟し、セキュリティ保証に対する信頼度が高まるにつれて、より広範なユーザーセットに徐々にリリースできます。

運用フェーズ

運用フェーズでは、 セキュリティ ギャップを修正する最後の責任ある機会が示されます。 運用環境でリリースされたゴールデン イメージの記録を保持します。

バージョン管理された成果物を保持する

デプロイされたすべての資産とそのバージョンのカタログを保持します。 この情報は、インシデントトリアージ中、問題を軽減するとき、およびシステムを動作状態に戻すときに役立ちます。 バージョン管理された資産は、公開されている一般的な脆弱性と露出 (CVE) の通知と比較することもできます。 これらの比較を実行するには、自動化を使用する必要があります。

緊急修正

自動化されたパイプライン設計では、 通常のデプロイと緊急デプロイの両方を柔軟にサポートできる必要があります。 この柔軟性は、迅速で責任あるセキュリティ修正をサポートするために重要です。

通常、リリースは複数の承認ゲートに関連付けられます。 セキュリティ修正を高速化するための緊急プロセスを作成することを検討してください。 このプロセスには、チーム間のコミュニケーションが含まれる場合があります。 パイプラインでは、通常のデプロイ ライフサイクルの外部で発生するセキュリティ修正、重大なバグ、コード更新に対処する、迅速なロールフォワードデプロイとロールバックデプロイを可能にする必要があります。

注意

利便性よりも常にセキュリティ修正に優先順位を付けます。 セキュリティ修正では、回帰やバグを導入しないでください。 緊急パイプラインを通じて修正プログラムを高速化する場合は、バイパスできる自動テストを慎重に検討してください。 各テストの値を実行時間で評価します。 たとえば、単体テストは通常、迅速に完了します。 統合またはエンドツーエンドのテストは時間がかかる場合があります。

メンテナンス フェーズ

このフェーズの目的は、 セキュリティ体制が時間の経過と同時に減衰しないようにすることです。 SDLC は、継続的なアジャイル プロセスです。 前のフェーズで説明した概念は、要件が時間の経過と同時に変化するため、このフェーズに適用されます。

更新プログラムの管理。 セキュリティパッチと更新プログラムを使用して、ソフトウェア、ライブラリ、インフラストラクチャコンポーネントを最新の状態に保ちます。

継続的な改善。 コード レビュー、フィードバック、学習した教訓、進化する脅威を考慮して、ソフトウェア開発プロセスのセキュリティを継続的に評価し、改善します。

古い、または使用されなくなったレガシ資産の使用を停止します。 これにより、アプリケーションの表面領域が減少します。

メンテナンスには、インシデントの修正も含まれます。 運用環境で問題が見つかった場合は、繰り返されないように、すぐにプロセスに統合する必要があります。

セキュリティで保護されたコーディングプラクティスを継続的に改善して、脅威の状況に対応します。

Azure ファシリテーション

Microsoft セキュリティ開発ライフサイクル (SDL) では、開発ライフサイクルに適用できるセキュリティで保護されたプラクティスをお勧めします。 詳細については、「 Microsoft セキュリティ開発ライフサイクル」を参照してください。

Defender for DevOps と SAST ツールは、GitHub Advanced Securityまたは Azure DevOps の一部として含まれています。 これらのツールは、organizationのセキュリティ スコアを追跡するのに役立ちます。

これらのリソースで説明されている Azure セキュリティに関する推奨事項に従います。

ソース コードで資格情報を見つけるには、GitHub Advanced SecurityOWASP ソース コード分析ツールなどのツールの使用を検討してください。

アプリケーション内のオープンソース コードのセキュリティを検証します。 これらの無料のツールとリソースは、評価に役立ちます。

セキュリティ チェックリスト

推奨事項の完全なセットを参照してください。