[レポート] セキュアなソフトウェア配信ライフサイクルのためのベストプラクティス #DOP316 #reinvent

2023.04.30

アノテーション テクニカルサポートの川崎です。

本記事は AWS re:Invent 2022 のセッションレポートとなります。

概要

このセッションでは、AWS で CI/CD パイプラインを保護する方法について学びます。 パイプラインのセキュリティとパイプライン内のセキュリティ、さまざまなパイプライン ステージにセキュリティ チェックポイントを組み込む方法、セキュリティ イベント管理、脆弱性の検出結果を 1 つの画面に集約する方法などのトピックを確認します。 また、アプリケーションとサービスを安全な方法で提供する組織の能力を向上させることができるベストプラクティス、プロセス、およびツールについても説明します。

セッション動画

セッション資料

Best practices for securing your software delivery lifecycle

セッション情報

DOP316

はじめに

最近のセキュリティの課題の一つとして、急速に増加するセキュリティツールの数があります。顧客はどのツールを選択すべきか迷ってしまうことが多く、市場でベストプラクティスを判断するのが難しくなっています。組織では、セキュリティやコンプライアンスといった分野とDevOpsやソフトウェアセキュリティライフサイクルの統合が困難になっていることも問題です。適切な統合ポイントがないため、統合を行うこと自体が難しい状況です。 また、組織はセキュリティインシデントに対応することが難しくなっています。クラウドへの移行や環境の複雑さの増加により、どのような対応をすべきか、アラームが鳴ったときにどこで反応するか、どのサービスを調べたりログを使用すべきかといった判断が難しくなっています。特に、マイクロサービスベースのワークロードやモノリスからの移行による環境の複雑さは、セキュリティフットプリントを管理する際により困難になっています。 どのように自動化し、効果的に対応するか、そしてどのツールが役に立つのかを知ることは今日のお客様が直面している重要な課題です。このセッションを通じて、その一部について理解を深めていただければ幸いです。

別のアプローチが必要な理由

なぜ別のアプローチが必要なのでしょうか。歴史的に私たちがセキュリティをどのように行っていたか、または多くの組織で現在セキュリティをどのように行っているかを見ますと、エッジを保護するために多くの時間を費やしています。しかし、攻撃者は非常に狡猾的であり、別の方法で侵入しています。そのため、彼らに対して効果的な防御をするためには、別のアプローチが必要です。 また、開発作業やアプリケーションのビルドなどのプロセスは、時に煩わしいと感じられることがあります。プロジェクトが長期に渡ると、QA チームによる検証の後に、アプリケーションに問題が見つかることがあります。しかし、開発者は新しい機能を開発するために多忙であり、問題への対応ができないことがあります。 このような状況から、別のアプローチが必要であることが理解できます。新しいアプローチには、セキュリティ対策を効果的に行うだけでなく、開発チームと連携し、問題の早期解決に取り組むことが含まれます。従来の方法よりも効果的なセキュリティ対策と問題解決のアプローチが求められているのです。

変化の外部要因

2020年から2021年にかけて、サプライチェーン攻撃の件数が650%増加したという外部要因も見られました。 アプリケーション・パッケージにオープンソースとして使用された依存関係の数は、 以前は75〜80%であったのが、ここ数年で98%まで増加しました。 人々が見つけているセキュリティ問題の81%は、オープンソースソフトウェアパッケージに関するものである、 という興味深い統計の数字もありました。 そのため、サプライチェーンを把握し問題の根本原因を解決する必要があります。 例えば、ファイアウォールのように事後対処するのではなく、その問題をエッジ(未発生状態)で解決しようとするのです。 ここでDevSecOpsが重要な役割を果たします。DevSecOpsは、開発チームと運用チームが共に働く哲学であるDevOpsが基盤となります。 DevOpsは開発チームと運用チームの間の壁を取り払うものであり、それはツールよりもコミュニケーションの障壁を打破することが重要です。 お互いに協力し、アイデアを共有することが大切です。 DevSecOpsは、そのDevOpsの考え方にセキュリティを組み込むものであり、開発・運用チームと一緒にセキュリティを最初から考慮し、脅威モデルを作成することが求められます。セキュリティは最後に考えるべきものではなく、全体論的に考えるべきです。さらに、DevSecOpsはただのチームではなく、それぞれのチームが共に働くという哲学であり、製品の質を向上させ、より速いペースで機能を追加することができます。

修理コスト

私たちが知っていることは、修理コストがソフトウェア配信ライフサイクルが進むにつれて増加していくことです。 たとえば、開発者がデスクトップの問題を修正した場合、それが解決されるかどうかを確認することができます。 これは一般的な知識であり、DevSecOpsが必要な理由でもあります。 スキャンやシフトレフトといった概念を考慮して、セキュリティについても考える必要があります。 しかし、すべての問題が開発者のデスクトップで解決されるわけではありません。 開発ライフサイクルの中で、運用チームがこれらの問題の一部を解決する必要があることがわかります。 これを右にシフトする(shift right)と言います。 結局のところ、わからないことはわからないわけです。 ここで、AWSの一部の開発者ツールについて話をしましょう。これはコンテキストを提供するために役立ちます。 要約すると、ソフトウェア配信ライフサイクルが進むにつれて修理コストが増加することが一般的です。 これはDevSecOpsの重要性を示しています。 セキュリティやスキャンなどの概念を考慮して、シフトレフトやシフトライトすることが必要です。 また、AWSの開発者ツールもコンテキストの提供に役立ちます。

開発者ツールのポートフォリオ

開発者ツールのポートフォリオについて説明します。 私たちはさまざまな開発者ツールを利用しており、GitHubやGitLabのようなサービスを用いる場合もあります。 ここでのポイントは、これらのツールが一般化されていて、どのようなツールやライフサイクルでも適用できるということです。 私たちの開発者ポートフォリオには、CI/CD ツール、ML ツール、IDE ツールキットなどが含まれています。 また、私たちにとって非常に重要なSDKも用意されています。AWSのサービスを活用するだけではなく、 「指数関数的バックオフ」やジッタなどのベストプラクティスを実現することができます。 私たちの開発者ツールのエコシステムは、幅広い製品であるだけでなく、深い製品でもあります。 しかし、特定のツールを使用する必要はありません。 実際に、私たちはサードパーティと協力して、インテグレーションを構築することができます。 サードパーティのソリューションを利用している場合、CodeCommitやCodeBuildのようなツールの代わりに、シームレスなプロセスが望ましいでしょう。 私たちは引き続きこれらのツールを活用し、AWS上でワークロードを実行し、保護することの成功を確認したいと考えています。 特定のシナリオやツールセットを購入する必要はありませんが、それらがうまく機能するように構築されていることを理解することが大切です。 お互いにコミュニケーションができるように、統合は簡素化されています。 多くの場合、特定のソリューションを自分で管理する必要はありません。 AWSサービスの一部を利用することは本質的な価値があります。 例えば、EC2インスタンスなどのインスタンスにおいて、ワークロード自体と共にセキュリティを維持するために試行や管理が必要となります。 最後に、CodeCommitについて触れます。CodeCommitは基本的にGitリポジトリであり、開発者が利用できる重要なツールの一つです。

AWS CodeCommit

AWS CodeCommitは、安全なGitベースのリポジトリで、AWSアカウント内に存在し、開発者が簡単に利用できるようになっています。 これはプライベートリポジトリで、IAMポリシーを利用してAWSの他のサービスと統合できます。 CodeCommitでは、異なるトランザクションを行う際にGitのようにチェックインを行い、CloudWatch Events を通じてイベントを発行します。 また、CodeBuildは汎用的なビルドツールであり、事前パッケージ化されたイメージやカスタムビルドイメージを使用してビルドジョブを実行できます。 さらに、ビルドとテストプロセスのサポートのために、buildspec.yamlファイルが提供されています。 CodeArtifactはアーティファクトリポジトリで、AWSアカウント内に存在します。 これにより、npmやpip、mavenのような依存関係を管理できます。 場合によっては、依存関係がCodeArtifactにない場合も、必要なアーティファクトを取得できます。 また、セキュリティの観点からポリシーを適用することが可能です。 CodeDeployはアプリケーションのデプロイメントを管理するツールで、ロールバック機能が強化されています。 これにより、アプリケーションを悪い状態にロールバックすることなくデプロイメントを管理できます。 CodePipelineはこれらのツールを統合し、オーケストレーションを提供します。 これにより、コードのビルド、テスト、デプロイなどのプロセスが自動化されます。 AWSでは、パイプラインのセキュリティを2つの観点で検討できます。 1つ目は、アプリケーションがパイプラインを通過する際のセキュリティで、静的コード解析などのテストを実行できます。 2つ目は、パイプライン自体をアプリケーションとして考慮し、アクセス制限やパッチ適用などのベストプラクティスを実行する必要があります。 以上のように、AWS CodeCommit、CodeBuild、CodeArtifact、CodeDeploy、CodePipeline は、開発からデプロイメントに至るまでのソフトウェア開発プロセスを効率的かつセキュアに管理するためのツールです。これらのツールを活用することで、開発チームはより迅速かつ安全にアプリケーションを開発、デプロイできるようになります。

SLSA フレームワーク

SLSAフレームワークについての概要です。 SLSAフレームワークは、オープンソースのベストプラクティスに関するガイダンスを提供するクリエイティブ コモンズ フレームワークです。 これは、実際のパイプライン自体を保護する方法について、さまざまな段階ごとのガイダンスに焦点を当てています。 具体的には、パイプラインのさまざまなポイントで考慮すべきことや、保護策に関するアドバイスが提供されています。 まずは、ソースの完全性についてです。 これは、ソース周りの脅威や、コードレビュープロセスの回避、レビューなしで変更を送信できるような脆弱性の管理に関連しています。 また、ソースリポジトリがどのように侵害され得るかについても説明されています。 軽減策としては、例えば、2人の査読者が変更を確認するように求めたり、マージのプロセスに特定のルールを適用したりすることが挙げられます。 さらに、スーパーユーザーアクセスやコードレビューが不十分な場合の対策についても触れられています。 例として、リード開発者が独自に変更を加えることや、プロジェクトの操作に関する緊急事態が発生した際、チェックとバランスを導入することの重要性が強調されています。 そのため、リード開発者であっても、適切なチェックとバランスがなければ変更を行うことは危険であるとされています。 SLSAフレームワークが提供するソリューションの1つとして、親切なアプローチが推奨されています。 これにより、開発者やプロジェクトの安全性やパイプラインの保護が向上し、オープンソースプロジェクトの品質が向上することが期待できます。 このように、SLSAフレームワークは、ソフトウェア開発におけるセキュリティや品質管理のための包括的なガイダンスを提供しています。 これを活用することで、開発者はより安全で信頼性の高いオープンソースプロジェクトを実現することができ、その結果、エンドユーザーにとっても利益が生まれます。

ソリューション: ソースの整合性

ここでは、ソースの整合性を向上させるために、特定のユースケースに焦点を当てていきます。 少なくとも2人に査読を依頼することで、特定の開発者がパイプラインへのマージを実行できないようにするアプローチを提案しています。 この目的を達成するために、IAMポリシーを設定し、CodeCommit内でのマージを制限します。 CodeCommitを利用した場合、マージリクエストやプルリクエストが発生すると、Amazon EventBridge にイベントが送信されます。 EventBridge は、Lambdaジョブを起動して、リポジトリ内のピアレビューが実施され、プルリクエストを送信した人と異なる誰かがマージを実行するかどうかを確認します。 マージが成功した場合、マージされたブランチは削除され、SNSを使用して通知が開発者に送られます。 このアプローチにより、責任の範囲が明確になり、マージを実行しようとする開発者がいなくなります。 SLSAフレームワークの概念として、ビルドの整合性も言及されており、非公式のフォークや異なるビルド環境に対する対策が提案されています。 ここではまた、ビルドのタイプやブランチによって、異なる脅威への対処方法について説明します。 例えば、ワイルドカードを利用して任意のブランチからのビルドを制限することが提案されています。 また、命名規則を利用して特定のブランチをターゲットにすることができます。 攻撃者は、ソフトウェア開発ライフサイクルの初期段階でより弱いセキュリティ対策に対処しようとすることが認識されています。 開発者とプロセスの初期段階では、セキュリティが十分でない場合があります。 攻撃者は、早い段階でスタックにアクセスする方法を見つけることができます。 現実的な脅威に対処するために、開発者はソースの整合性に注意を払い、適切なセキュリティ対策を適用することが重要です。 開発の早い段階から監視が行われていない場合は、侵害した環境を使用した攻撃に対してリスクが高まります。 そのため、開発者は早い段階からセキュリティ対策を適用して、攻撃者に対する防御を強化しましょう。

ソリューション: 整合性の構築

以下に、ビルドの整合性のためのソリューションをまとめます。 まず、承認された依存関係を使用して構築することが重要です。 セキュリティは、セキュリティ部門やスキャンツールによって確保されています。 このソリューションでは、オーケストレータとして、CodePipelineを使用します。 また、CodeCommitを使って、組織が所有するプライベートリポジトリにアクセスします。 次に、CodeBuildを使って、CodeArtifactに到達し、その興味深い機能を利用します。 その機能はパッケージ オリジン コントロールと呼ばれ、ターゲットを設定できるようになります。 これはパッケージの出所やどこでテストされたかを特定することが重要だからです。 内部パッケージでは、使用されている命名規則を理解することが大切です。 例えば、パッケージ バージョン1を使っていて、バージョン1.1が登場した場合、それをパブリックリポジトリに移すことができます。 その後、パッケージマネージャーは演算ができ、更新バージョンが利用できるようになります。 パッケージ オリジン コントロールでは、どちらがマスターであるか指示し、基本的に内部のものがマスターソースだと言えます。 サプライチェーン攻撃のリスクを減らすために、AWS CodeArtifactを使用します。 AWS CodeArtifactは、エフェメラル(一時的)な環境をデプロイする際に役立ちます。 一時的な環境は、環境に出てはいけない、インフラストラクチャコードや変更を行うために使用されます。 これらの環境での変更はGitで行われます。 一時的な環境を使用することの利点は、環境内で発生することが全て妥協されることを意味するため、特定の問題が発生した際に対処が可能です。 例えば、誰かがSSHにログインした場合、そのインスタンスを隔離することができます。 このソリューションでは、AWS構成も含まれており、それを使用することで変更が検出されます。 検出されたイベントはAWS Config によって取り扱われ、configルールを使ってそのイベントを検出することができます。 イベントが検出されると、アラームをSNSに送信し、Slackメッセージなどで通知ができます。 また、SecurityHubやその他のサービスに送信したり、メールでも知らせることができます。

可用性とその他の脅威

可用性とその他の脅威について説明します。 私が実際に個人的に経験した可用性の脅威の一つは、ジョブをビルドする場合や、ビルドを行っている途中で、コード内にさまざまな依存関係があることです。 その依存関係が外部ソースから利用できない場合、ビルドジョブは基本的に停止してしまいます。 これ以上進めることはできません。 しかし、いつその可用性が回復するかはわかりません。 公開リポジトリや特定のパッケージが3日間ダウンすると、3日間待たなければなりません。 そこで考えられるソリューションは、実際に保存していつでも利用できる独自のパッケージリソースを用意することです。 これにより、公開パッケージが利用できない場合でも、ローカルソースから直接プルして欠点を軽減できます。 他の緩和策として、バージョン管理や履歴の保持も重要です。 これについては、導入しているソリューションとともに説明します。 例えば、JfrogのようなアーティファクトリポジトリやCodeArtifactの利用が重要です。 Docker Hubなどのインターネット上のリポジトリから直接プルするのではなく、いつでも利用可能なローカルソースからプルすることが理想です。 私は以前、node.js用の乱数ジェネレーターがあり、そのライブラリがオフラインになり、直接の依存関係でなくても、他の多くのものが壊れ、最終的にアプリケーションが破損する経験をしました。 このことから、常にローカルソースからプルできる状態を保つことが重要です。 また、セキュリティの観点からも、スキャン可能なリソースであることが望ましいです。 以上のことから、ソリューションを構築する際は、ソースやアーティファクトの可用性を考慮して計画してください。 これにより、外部ソースからの影響を最小限に抑えられるでしょう。

ソリューション: ソースとアーティファクトの可用性

まず、AWS内でデータを管理する際、冗長性のためにデータを複製して隣接するAWSアカウントに保存しているケースがありますが、その際は読み取り専用で保持することを考慮してください。 実際の事例として、ある企業がデータの剪定を行ったところ、約500ギガバイトもの大量のデータが削除されました。 それでも、リポジトリからのデータの複製がうまく機能していたため、すぐにデータを復元することができました。 しかし、復元には6か月ほどの時間がかかったため、バックアップからのデータ復元が非常に重要であることがわかります。 次に、データをCodeCommitアーティファクトリポジトリのような別のアカウントにコピーすることを考えた場合、保存しているデータは追加のみであるため、問題はありません。 もし誰かがデータの剪定を行っても、履歴があるため他のアカウントに複製することができます。 セキュリティ面でも、データが侵害された場合にも、クリーンなソースからプルして置き換えることができます。このため、データの複製やバックアップは非常に重要なプロセスです。悪意のある者はログの情報を正確に把握しており、ログをクリーンアップする方法も知っています。そのため、追加のみという制限がある場合であっても、データの改ざんができないように、別のアカウント内にデータを保持しておくことが大切です。また、アクセスできる人数も厳密に制限しておくことがセキュリティ対策につながります。 以上のような理由から、AWS内でデータを管理する際は、より安全かつ効率的なデータバックアップや復元を行うことが重要です。

依存関係を確認する

依存関係を確認することについて話しましょう。後ほど Curtis が SBOM について説明しますが、依存関係をチェックする際に重要なことは、実際にチェックできるSBOMが必要だということです。 これは、来歴を検証し、署名を検証していることを意味します。 Curtis は SBOM に何が含まれているか、検証が必要かについて話しますが、基本的にはビルドの正確さを確認することが必要です。 これらのハッシュを検証するテスト手順に加え、パッケージにハッシュが含まれているか確認し、実際にダウンロードしたハッシュがベンダーのものと一致するかチェックする必要があります。 このプロセスは自動化が可能で、コンテナ内のOPA(オープンポリシーエージェント)でよく見られます。 実際にデプロイしているものが期待するものであることを確認するために、クラスターでハッシュを検証し、依存関係をチェックします。 ただ信頼するだけでは十分でなく、それだけに基づくリスクを軽減したいと考えています。 ガードレールは、イベントの発生や影響範囲を減らす効果があります。 例として、Amazonでは生産アカウントの管理にガードレールが設定されており、S3バケットの作成を制限しています。 パブリックS3バケットがセキュリティリスクがあることを知っているため、開発者はパブリックS3バケットを作成する際に警告を受ける必要があります。 しかし、開発者は意図的にパブリックS3バケットを作成する場合があります。 ガードレールは、開発者の作業を邪魔するものではなく、意図的な行動を確認し、彼らが何をしているかを意識させることが目的です。 パブリックS3バケットのような場合、ガードレールは開発者が実際にやりたいことを確認する重要な役割を果たします。 以上の内容から、依存関係の確認やSBOMの検証はアプリケーション安全性の重要な部分であり、自動化やガードレールを活用してリスクを軽減することが可能です。 開発者はこれらのプロセスを遵守し、セキュリティと品質を確保することが求められます。

ガードレール

ガードレールについての重要なポイントであるセキュリティについて述べます。 私たちは、セキュリティが厳格なプロセスと見なされることを望んでいませんが、意識的なプロセスであることを確認したいと考えています。 例えば、あるイベントで「ねえ」と確認したいように、「これはあなたが本当にやりたいことを行っているのか、それともこれが作成されるリスクなのか」という疑問が生じることがあります。 このような場合、問題が発生しても追跡や管理ができることが重要です。 例えば、ある人がバケットを作成したときに、フラグが表示されるような仕組みがあると便利です。 これにより、チームのメンバーがバケットを作成したことを知ることができます。 このようなことを追跡し、できるだけ自動化することが重要なポイントです。 その実例として、OPA(オープンポリシーエージェント)を使用しているケースが挙げられます。 OPAは、ポリシーを定義できるようにするテクノロジーとツールで、ポリシーと実装を分離することができます。 これにより、より効果的なガードレールの仕組みを構築できます。 最終的に、ガードレールにおけるセキュリティは、厳格なプロセスではなく、意識的で追跡可能な仕組みを整えることが求められます。 また、自動化を活用し、効果的な管理ができるようにすることも重要であると言えるでしょう。

ガードレールの例: コードとしてのポリシー

ガードレールの例として、コードとしてのポリシーについて説明します。 これは、EKSなどの制御と実施が行われる際にデプロイできる constraint.yaml に関連する話題です。 ポリシーでは、開発者やデプロイを行おうとしている人がプライベートリポジトリからコンテナをデプロイしようとする場合は許可されますが、パブリックリポジトリからコンテナをデプロイしようとすると、これを防止する仕組みがあります。 開発者としては、必ずしも理解できない事情があることを認識しておく必要があります。 このようなポリシーを使用することで、コンテナのデプロイが不当に妨げられることはありません。 もし本当にデプロイしたいコンテナがある場合は、プライベートなコンテナリポジトリを作成し、そこからポリシーに従ってスキャンなどの処理を行い、悪意のあるコンテナでないことを確認する必要があります。 この方法により、安全なコンテナのデプロイが実現され、不正なコンテナに対する対策が強化されます。

パイプラインのセキュリティ: 考慮事項

前述の通り、パイプラインのセキュリティに関して最終的なセキュリティ上の考慮事項が必要です。 パイプライン自体をアプリケーションとして考えるべきで、秘密情報の保管方法や他者がアクセスできないような構成の保存方法など、様々な点を考慮する必要があります。 悪意のあるアクターが攻撃できる場合、パイプラインの構成を変更することで、実際のパイプライン自体に大きな損害を与える可能性があります。 ビルドプロセスがどのように行われるかを制御できるようにすることで、依存関係を変更する可能性がある様々な事象を挿入できます。 そのため、アプリケーションとしてパイプライン自体を考慮する必要があります。 さて、パイプライン自体を保護する方法について話しましたが、パイプラインをエンティティとして保護することに加えて、実際にそれを介して物を移動する方法やパイプライン内の要素をどのように保護するかについても考慮する必要があります。 これらの要素を総合して、パイプラインのセキュリティ対策を十分に行うことが重要です。

概要: パイプラインのセキュリティ

パイプラインのセキュリティについての概要を説明します。 パイプライン内には複数のステージがあり、それぞれ特定のセキュリティタスクを実行する機会があります。 コードステージでは、開発者が書いたコードやその脆弱性をスキャンすることができます。 ソースコードリポジトリに保存する前に脆弱性をチェックし、セキュリティを向上させることができます。 次にビルドステージでは、コードを構築し、アーティファクトを作成します。 ここでは、使用されるライブラリやダウンストリームからのコンポーネントにどのようなセキュリティリスクがあるか考慮する必要があります。 リスクを軽減するための対策を講じることが求められます。 テストステージでは、アプリケーションを実行し、侵入テストや負荷テストを実施します。 これにより、実行中のアプリケーションに対するセキュリティリスクを特定し、対応が可能となります。 デプロイステージでは、アーティファクトを本番環境にデプロイします。 この際、セキュリティチェックを行い、検証済みのアーティファクトを使用していることを確認します。 ハッシュが一致しない場合、パイプラインを停止し、セキュリティチームや運用チームに警告を出すことができます。 本番環境での実行では、継続的な監視が必要です。 ランタイムスキャンが導入されることで、アプリケーションのセキュリティを維持し、問題が発生した際に素早く対応することができます。 以上の各ステージにおいて、セキュリティタスクを実行し、アプリケーションの安全性を高めることができます。 パイプライン全体を通じて、セキュリティ対策を強化し、アプリケーションの堅牢性を向上させることが重要です。

ソースコード内の機密情報

では、これらの機会についてもう少し詳細に見ていきましょう。 開発の初期段階で、開発者はすでにコードを書いており、これは機密情報のスキャンを開始する機会です。 この会場にいる開発者の何人かは、以前にローカルデータベースのユーザー名やパスワードを使ったことがあるでしょう。 一部の開発者は、ローカル環境変数を使って、ユーザー名やパスワードがコードに含まれないようにアクセスし、動的に参照しています。 ただし、例えば、金曜の夜に開発が進行中で、思わずコードに追加してしまうこともあります。 こういった状況で、コードを保存する際にリアルタイムでスキャンできるプラグインを開発者に提供することができるチャンスです。 これにより、開発者は誤ってコードに機密情報が含まれてしまったことをすぐに知ることができます。 Git Hooksのような仕組みも同様に機能します。 AWSには、Code Definer というツールがあります。 Specter Cloud という製品も存在しますが、これも同じ目的で動作し、Gitコミット時にスキャンがトリガーされるように設定されています。 このようにして、すぐに機密情報の含まれた部分を特定し、修正することができます。 また、これによりGitリポジトリの履歴がクレンジングされていく過程を確認することができます。 このプロセスは、リポジトリやリスクの数を通知し始めます。 これらのリスクに基づいて、傾向が上向きか下向きかを判断できます。 開発者は開発者をサポートする目的で存在しているため、このような機能は追加の負担ではなく、開発にとって非常に有益です。 リポジトリで定期的にスキャンを行うことで、プルリクエストを通じて漏れた情報がないか、レビュープロセスで漏れた情報がないかを確認できます。 また、新しい脆弱性に関するデータでツールが更新された場合、再度スキャンし、必要に応じて修正することができます。

ソフトウェア構成分析 (SCA)

ソフトウェア構成分析(SCA)は、開発スタックの下層部に目を向け、コードの依存関係を調べ、スキャンし始める機会が提供されます。 例えば、Node 開発者が4行のノードアプリケーションを書いた際、その後に4000のライブラリを使用して npm ビルドを実行し、大規模なアプリケーションになります。 この時、4000の依存関係をチェックし、それらをスキャンすることができます。 アプリケーションの依存関係をスキャンして、下流に脆弱性が存在しないことを確認するために、OWASP 依存関係トラッカーなどのオープンソースソリューションを使用できます。 さらに良い方法として、自動スキャンが可能なローカルリポジトリにそれらをプルダウンし、検証して埋め込むことが挙げられます。 このプロセス全体を通して重要なポイントは、一度にすべてを変更しようとせず、成長を続けながら徐々に積み重ねていくことです。 新しいステップを1つずつ導入し、一定期間の成長を促進することで、成熟度を高めることができます。 時間の経過とともに、Snyk や Mend、Anchore などのツールが役立ち、採用と成長の過程で問題を緩和します。 このような取り組みを継続することで、組織全体のセキュリティレベルを向上させることができます。

静的アプリケーション セキュリティ テスト (SAST)

静的アプリケーションセキュリティテスト (SAST) について解説します。 SASTは、開発プロセスの早期に行われるセキュリティテストで、一定の期間内で行われるスプリントにおいても活用できます。 これにより、既知の脆弱性を特定し、後半の開発サイクルでも対処することができます。 具体的には、ホワイトボックステストのような方法で、コードベースや依存関係をスキャンし、既知の問題を検出します。 これによって、ビルドプロセスやパイプラインに入る前に問題をキャッチすることができます。 重要なのは、スプリントの期間中にこれらのツールを使用して脆弱性を特定し、修正が必要かどうかを判断できることです。 もしリスクが低いと判断された場合は、次のスプリントで対応することができます。 また、新しい脆弱性が見つかるたびに、コードベースを定期的にスキャンすることが重要です。 これにより、新しい脆弱性に対応しながら適応していくことが可能となります。 SAST を行うためのソリューションとしては、Snyk、SonarQube や Amazon CodeGuru などがあります。 これらのツールは、ビルドの様々な段階で有用であり、アプリケーションを定期的にスキャンすることができます。 また、プルリクエストが行われる際にも、既知の脆弱性について検出することが可能です。 SAST を効果的に活用することで、早期の段階からセキュリティの問題を把握し、開発プロセス全体の安全性を向上させることができます。 開発チームは、これらのテストを適切に活用することで、セキュリティリスクを最小限に抑え、より安全なアプリケーションを提供できるようになります。

動的アプリケーション セキュリティ テスト (DAST)

動的アプリケーションセキュリティテスト(DAST)は、開発パイプラインの中でアプリケーションをビルドした後に行われるセキュリティテストです。 このテストは、実行中のアプリケーションに対して行われるため、ブラックボックステストと見なされています。 これはコードベース自体には直接アクセスできないものの、利用者の立場で実行中のアプリケーションをテストすることができます。 DAST は、現実世界で実際の攻撃者が行うような手法でアプリケーションをテストすることを考えています。 攻撃者は開いたままのポートや SQL インジェクションの脆弱性を突くことができます。 これは要するに、実行中のアプリケーションやバックドアに侵入することを試みます。 ツールの1つである OWASP zap を使用して、DAST を実行し、アプリケーションをスキャンすることができます。 このテストの課題は、すでに作成されているコードに非常に集中しており、すでに存在する脆弱性を検出することに重点を置いていることです。 新しい脆弱性が発見されるわけではなく、既存のものについて認識を深めることが目的です。 DAST は、実行中のコードの脆弱性を特定し、開放されたままのポートや他のリスク要因を明らかにするのに役立ちます。 コードを直接見ることができないため、オブザーバビリティや監視などの手法を利用し、アプリケーションのセキュリティ状況を評価します。 このテストは本番環境へのリリース前に実施され、追加の脆弱性を見つけ出し、悪用される前に侵入されるリスクを減らすことができます。 いざ本番環境になると、様々な要因が絡むため、完全なセキュリティを保証することはできませんが、DASTはそのリスクを最小限に抑える上で非常に重要な役割を果たしています。

ランタイム アプリケーション自己保護 (RASP)

ランタイムアプリケーション自己保護(RASP)についての概要を説明します。 RASP は、実行中のアプリケーションにおいてアクティブな脅威に対する保護を提供する技術です。 これは、動的アプリケーションテストとは異なります。 RASP は、実行中のコンテナにサイドカーを追加することで、リアルタイムで攻撃者の行動に対応しようとします。 たとえば、実行中のデプロイでシステムの一部でバイナリアプリケーションを実行している場合があります。 RASP は、通常、コンテナの監視やサーバーの監視を行うエージェントを介して実装されます。 リアルタイムで実行されているワークロードは、入ってくるすべてのデータを取得し、機械学習を利用して通常のベースラインを確立します。 このプロセスでは、リアルタイムで進行しているすべてのアクションが監視され、正常な動作と潜在的な脅威が判別されます。 RASP の利点は、Falco や Sysdig、Aqua などのツールを使用して、リアルタイムでアクションが実行できることです。 例えば、特定の場所からのトラフィックが検出された場合、不正なトラフィックと判断されると、リアルタイムでブロックすることでアプリケーションを保護する対策が講じられます。 これにより、コード自体から早い段階で複数のセキュリティレベルを利用することができます。 開発プロセスの中で、コードがビルドされたアーティファクトにコンパイルされた後、実行中のアプリケーションを保護するために、RASP は重要な要素となります。 アプリケーションのライフサイクル全体にわたるセキュリティと組み合わせて、ソフトウェア開発のライフサイクルにおいてこの技術が役立ちます。 以上のように、ランタイムアプリケーション自己保護(RASP)は、実行中のアプリケーションにおけるアクティブな脅威に対応する重要な技術です。 これにより、複数のセキュリティレベルを利用してアプリケーションを保護できます。 機械学習を用いたリアルタイムの監視とアクションが実行できるツールを使用することで、アプリケーションのライフサイクル全体にわたるセキュリティを向上させることができます。

テストと分析

この話題は、開始と終了を定めるものではありません。 現実のすべてと同様に、I-chart で表されますので、すべてを網羅しません。 ここでは、セキュリティやオブザーバビリティが水平にあると捉えています。 また、これらはアプリケーションのデプロイ後だけでなく、開発サイクル全体を通じて持続的に発生します。 アプリケーションの計画時から始まり、DevSecOps の会話に戻ります。 ネットワーキングチームと話し合い、必要なポートについて理由を説明し、同意を得てコードに組み込みます。 また、パイプラインやインフラストラクチャのコードを構築し、サービス間での統合について話し合います。 さらに、アクセスと制御を許可する IAM ポリシーがあることや、適切なプロセスでシークレットが保存されていることを確認します。 開発ライフサイクル全体を通じて、ビルドからテストまでこの取り組みを継続します。 運用の展開には、静的コード分析やブラックボックステスト、ランタイムスキャンなど、各フェーズで役立つものを配置します。 目的は、これらすべてをカバーして、開発ライフサイクル全体を通じて適切なテストとチェックが実施されていることを確認することです。

テストとチェックの実装

テストとチェックの実装について説明します。AWS CodeCommit や CodeBuild を利用すると、イベントに基づいてアクションが実行されることができます。 これにより、コミットやビルドジョブの開始時に、スキャンをトリガーすることができます。 アイデアは、アプリケーションの構築とともに、アーティファクトの保存を開始し、適切なアクションを自動的にトリガーすることです。 手動で検証するのではなく、プロセス全体を自動化し、GitHub や Jenkins などのソリューションも利用できます。 重要なのは、状況に応じてすべての段階で適切なスキャンとアラートを行い、機会を利用することです。 先ほど言及されたソフトウェアの部品表の利用も含めて、それらを実現していくことが求められます。

ソフトウェア部品表 (SBOM)

ソフトウェア部品表(SBOM)は、一部の方にとっては少し抽象的な概念ですが、アプリケーションを構築する際に重要な考え方です。 アプリケーションには下流の依存関係があるため、脆弱性が発生した場合にどのアプリケーションが影響を受けるかを特定する必要があります。 例えば、100個の Java アプリケーションがある場合に、Java の特定のバージョンやバイナリライブラリに新しい脆弱性が見つかったら、どのアプリケーションが脆弱性を持っているかを特定するためにすべてのアプリケーションをスキャンする必要があります。 しかし、ソフトウェアの明細書(bill)のようなものを使って、アプリケーションとそのすべての依存関係をスキャンし、作成することができます。 このようなオープンソースのツールを使って、アプリケーションのすべてのコンポーネントを定義するドキュメントを作成することができます。 このプロセスを自動化できるため、手動で行う必要はなく、すべての依存関係を素早く見つけることができます。 このようなファイル形式を使うことで、依存関係を確認し、視覚化し、実際にスキャンすることができます。 これにより、実際の攻撃者やリスクがある場合に、迅速に対処できます。 例えば、特定の Java バージョンが脆弱性を持っていると分かった場合、400個のアプリケーションのうち27個がそのバージョンを使っていることが分かります。 また、どのバイナリライブラリを使用しているか、どのバージョンがあるかなど、詳細な情報も把握できます。 SBOM を使うことで、新しいアプリケーションを構築する際に、依存関係をロードし、適切なスキャンを行い、それらがあることを確認できます。 このプロセスは非常に強力ですが、それでも開発者との会話が必要です。 開発者はこの仕事が重要である理由を理解し、価値を伝えられるようになる必要があります。 問題が発生するたびに400のアプリケーションをスキャンするのは避けたいため、事前に作業を進めることで、開発者は脆弱性があるアプリケーションを見つけ、迅速に修正し、他の楽しい作業に戻ることができます。

オブザーバビリティ インストルメンテーション

オブザーバビリティの一部としてパイプラインの構築が行われ、さまざまなコンポーネントを含むプロセスが観察されます。 アプリケーションの実行中だけでなく、パイプライン自体も監視されるべきです。 様々なツールを用いてデータに対する観察や反応ができます。 異なるファイル形式や構造を手動で取り込むことは困難ですが、データレイクにロードしスキャンする方法があります。 ELK スタックの手動管理も大変な作業ですが、ADOT という理解を通じて、AWS のサービスからのデータとサードパーティのサービスデータを CloudWatch にフィードすることができます。 データは Data Dog や NewRelic にもフィードされます。 シンプルさを追求することで、理解が始まります。 パイプラインの構築において、すべてがイベントになります。 コードリポジトリのコミットやビルドプロセスもイベントとして扱われ、他のイベントと連携することができます。

セキュリティ アラートと体制管理

まず、ダッシュボードを作成する際には、関与しているすべてのチームやプロセスから情報を取得し、それを一元化することが重要です。 各チームは異なる役割を持っており、セキュリティチームや運用チームといった異なるペルソナを持つため、文脈化された情報を活用して SecurityHub にまとめられるようにする必要があります。 次に、セキュリティイベントが発生した際に、パートナーソリューションを通じて適切なデータを取得し、 一元化されたダッシュボードやシングル・グラス・ペイン(一つの画面で全ての必要な情報が閲覧できる)に表示することで、 即座にアクションを実行できるようにすることが求められます。 例えば、アプリケーションで脆弱性が悪用された場合、Falco などのツールがそれを検出し、SecurityHub にリアルタイムで通知することで、 開発者やセキュリティチームに警告を送ることができます。 また、オブザーバビリティを確保することも重要で、実行中のランタイムに対して完全なスタックオブザーバビリティを提供して、 セキュリティや運用状況をリアルタイムで把握することが求められます。 これには、エージェントを使用してインストールできる CloudWatch を利用したり、ECS や EKS でのデータ取得を容易に行えるようにする必要があります。 さらに、データのまとめ方も重要で、ADOT や X-ray などのツールを活用してアプリケーション内のトレースを行い、迅速かつ効果的にデータを一元化し、理解しやすい情報に整理することが推奨されています。 以上の要点を考慮して、セキュリティアラートと体制管理を効果的に行い、組織全体で安全なシステムを維持しましょう。

まとめ

  • セキュリティ上の課題
  • DevSecOps: シフトレフトとシフトライト
  • AWS 開発者ツールのポートフォリオ
  • パイプラインのセキュリティ
    • パイプラインを保護する方法に関する SLSA フレームワークとアドバイス
  • パイプライン内のセキュリティ
    • セキュリティをアプリケーションに組み込む方法に関するアドバイス
  • イベント管理
  • オブザーバビリティ

ステージから追い出されるまであと7秒しかないので、まとめます。 アプリケーションを保護する方法について学びました。 パイプラインからビルド、ランタイムシナリオ、さらにその先まで、アイデアは以下の通りです。 どこかで始めて、時間の経過とともに成長させてください。 すべてを一度に行う必要はありません。 しかし、アイデアは、それを行うために行動を起こすべきだということです。 詳細を知りたい場合は、ここにいくつかのリソースがあります。

本セッションの内容に興味を持たれた方は、上部のリンクからセッション動画、セッション資料をご覧ください。