CyberFix Note
セキュアコーディング

DevSecOps入門。CI/CDにセキュリティを組み込むSAST・DAST・SCA・シークレットスキャン

対象の目安: Webアプリ開発者・DevOps担当 / 実務レベル

ソウ攻撃・脆弱性リサーチ担当
・ 約15分で読めます
DevSecOps入門。CI/CDにセキュリティを組み込むSAST・DAST・SCA・シークレットスキャン

DevSecOpsは、これまで開発の最後に「検査」として行っていたセキュリティ確認を、開発と運用の流れ(CI/CD)の中に自動チェックとして組み込み、継続的に回す考え方です。難しい新技術ではなく、「いつ・誰が・何を確かめるか」という体制の置き換えに近いものです。リリース直前にまとめて脆弱性を見つけて慌てるのではなく、コードを書いた直後やプルリクエストの段階で機械的に気づける状態を作るのが狙いです。

なぜいまこれが重視されるのか。現代のアプリは大量の外部ライブラリの上に成り立ち、デプロイの頻度も上がりました。人手のレビューだけでは、変更のたびに毎回すべてを点検するのは現実的ではありません。一方で、脆弱性は早く見つかるほど修正コストが小さく、設計やコードを書いた直後なら数分で直せるものが、本番リリース後だと調査・修正・再テスト・再デプロイと膨らみます。この「早く見つけるほど安い」という性質を仕組みで活かすのがDevSecOpsであり、その実践原則が「シフトレフト」です。

この記事では、CI/CDに組み込む代表的な4つのチェック、すなわちSAST・DAST・SCA・シークレットスキャンが、それぞれ何を見つけ、何を見つけられないのかを原理から整理します。そのうえで、どの順番で導入し、ノイズ(誤検知)とどう付き合い、どこで「ビルドを止める/止めない」を線引きするかという、現場で必ず迷う判断基準まで掘り下げます。

まず全体像を、各チェックが「何を対象に、いつ動き、何が苦手か」という観点で一覧にします。導入順序の目安も付けました。

チェック対象主に見つけるもの苦手・限界導入の目安
シークレットスキャンソース・コミット履歴APIキー・パスワード等の混入用途は判定できない(要人手確認)最初に入れる
SCA依存ライブラリ一覧既知の脆弱性を持つ依存自作コードの欠陥は見ない早期に入れる
SASTソースコードコード上の脆弱なパターン実行時の文脈に弱く誤検知が出やすい慣れてから
DAST動作中のアプリ実際に攻撃が通る不具合網羅性が低く実行環境が必要仕上げに入れる

シフトレフトとは何か、なぜ効くのか

シフトレフトは、開発工程を左から右(要件・設計・実装・テスト・リリース・運用)に並べたとき、セキュリティの確認を可能な限り左、つまり早い段階に寄せる考え方です。狙いは精神論ではなく、コストの非対称性にあります。設計やコードを書いた直後の不具合は、書いた本人が文脈を覚えているうちに数分で直せます。これがリリース後に発覚すると、原因調査、影響範囲の特定、修正、回帰テスト、再デプロイ、場合によっては顧客対応まで連鎖し、桁違いに高くつきます。

ここで誤解しやすいのが、「シフトレフト=とにかく早く厳しくチェックすること」ではない点です。早い段階に寄せても、結果が大量のノイズで信頼されなければ開発者は無視するようになり、かえって形骸化します。シフトレフトが効くのは、「開発者が自分の変更の直後に、信頼できる形で、少ない手間で気づける」ときです。つまり自動化・低ノイズ・開発フローへの埋め込みがセットで初めて成立します。

メモ

シフトレフトは「右(運用側の監視やインシデント対応)を捨てる」という意味ではありません。早期検知を強化したうえで、すり抜けたものを運用で捉える多層防御にするのが本来の形です。左に寄せることと右を維持することは両立します。

OWASPのDevSecOps Guidelineも、できるだけ早く問題を検知することを目標に掲げ、まずリポジトリの認証情報漏えいの検査から始めて、静的・動的検査や構成スキャンを段階的に組み込む流れを示しています。最初から全部を完璧に入れるのではなく、効果が大きく導入しやすいものから積み上げる発想が現実的です。

SAST 静的解析が見つけるもの・見つけられないもの

SAST(Static Application Security Testing)は、アプリを動かさずにソースコードや中間表現を解析し、脆弱性につながりやすいパターンを検出します。代表的には、外部入力がエスケープされずSQL文や画面出力に流れている、危険な関数を使っている、ハードコードされた危険な設定がある、といった箇所です。コードを書いた直後やプルリクエストの段階で動かせるため、シフトレフトと相性がよいチェックです。

強みは網羅性です。実行されないコードパスも含めてソース全体を見られるので、テストで踏まれないルートの問題も拾えます。一方で弱点もはっきりしています。SASTは「このコードは危険に見える」を指摘しますが、「実際にその経路が攻撃可能か」までは判断できません。たとえば、入力が別の場所で十分に検証されていても、SASTはそれを追いきれず警告を出すことがあります。これが誤検知(false positive)です。逆に、設定ファイルや実行環境に依存する問題は見逃すこともあります(false negative)。

SASTを入れた初週に数百件の警告が出て、メンバーが見るのをやめてしまった。重大度でフィルタし、確認済みのものは抑制設定で消す運用にしてから、ようやく指摘が信頼されるようになった。

ある開発チームの運用担当の声(一般化した例)

ここから導ける実務上の判断は明確です。SASTは導入直後に大量の指摘が出るのが普通で、それをそのままビルド失敗にすると開発が止まります。最初は重大度の高いものだけを対象にし、確認したうえで問題なしと判断したものは記録を残して抑制(ベースライン化)し、新規に増えた指摘に注目する運用にすると、ノイズに埋もれず継続できます。SASTで扱う代表的なリスクの全体像は

が整理の土台になります。

DAST 動かして攻撃が通るかを確かめる

DAST(Dynamic Application Security Testing)は、実際に動作しているアプリに対して外部からリクエストを送り、攻撃が成立するかを確かめます。代表的なオープンソースツールにOWASP ZAPがあり、Webアプリに対する自動スキャンを無償で行えます。SASTがソースを読むのに対し、DASTはブラウザや攻撃者と同じ「外側」から見るため、実行時の設定やサーバの構成も含めた実態に近い結果が得られます。

DASTの価値は、SASTの弱点をちょうど補う点にあります。SASTが「危険に見えるが実際に通るかは不明」を出すのに対し、DASTは「実際にこの入力で問題が再現した」を示せるため、誤検知が比較的少なく、優先度を判断しやすいのが利点です。一方で苦手も明確です。外から触れる範囲しか検査できないため網羅性は低く、認証が必要な画面や複雑な業務フローの奥は到達しづらい。さらに、動作する環境(ステージング等)とテストデータが必要で、スキャンに時間もかかります。

注意

DASTは実際にリクエストを送り込むため、対象を間違えると問題になります。スキャンは必ず自分が管理する環境、または明示的に許可された対象だけに限定してください。本番環境や第三者のシステムへ無断でスキャンを行うと、不正アクセス禁止法等に抵触するおそれがあります。テストデータの書き換えや負荷にも注意し、隔離された検証環境で実施するのが原則です。

導入のタイミングとしては、DASTはCI/CDの中でも仕上げ寄りに置くのが現実的です。毎回のプルリクエストでフルスキャンを回すと遅すぎるため、軽量なスキャンをプルリク時に、本格的なスキャンを夜間バッチやリリース前のパイプラインで、と頻度を分けるのが定石です。

SCA 依存ライブラリの既知の脆弱性を追う

SCA(Software Composition Analysis)は、アプリが利用している外部ライブラリ(オープンソース依存)を洗い出し、その中に既知の脆弱性を持つバージョンが含まれていないかを照合します。自分の書いたコードがどれだけ堅牢でも、依存ライブラリに既知の脆弱性があれば、そこが侵入口になります。現代のアプリはコード量の大半が外部依存で占められることも珍しくなく、SCAは「自作コードを見るSAST」と対をなす、攻撃面の管理に欠かせないチェックです。

SCAの効きの良さは、判定根拠が明確な点にあります。検出は「このライブラリのこのバージョンに、この脆弱性(CVE)がある」という公開情報との突き合わせなので、SASTのような曖昧さが少なく、対応も「該当バージョンを上げる」と方針が立てやすい。導入も比較的容易で、依存定義ファイルを読むだけで動くツールが多く、効果に対して着手コストが小さいため、シークレットスキャンと並んで最初に入れる価値が高いチェックです。

ただし限界もあります。SCAが見るのは「既知の」脆弱性であり、まだ公表されていない問題は対象外です。また、脆弱性のある関数を実際に呼んでいるかまでは判定しない(呼んでいなくても警告が出る)ツールもあり、すべてを即座に直す必要があるとは限りません。前提として、何をどのバージョンで使っているかを一覧化したSBOM(部品表)を持っておくと、新しい脆弱性が公表されたときに「自分は影響を受けるか」を即座に判断できます。

  1. 1

    依存を一覧化する(SBOM)

    使用しているライブラリと正確なバージョンを機械可読な形で把握します。これが脆弱性照合と影響範囲調査の土台になります。

  2. 2

    CIでSCAを回す

    プルリクエストやマージのたびに依存を照合し、既知の脆弱性を含む依存が増えていないかを検知します。

  3. 3

    重大度と到達性で優先度を付ける

    すべてを同時に直すのは非現実的です。重大度が高く、実際に呼び出している経路があるものから対応します。

  4. 4

    小さく頻繁に更新する

    放置するほど一括更新の負担が膨らみます。日常的に少しずつバージョンを上げる運用が結局は低コストです。

シークレットスキャン 機密の混入を入口で止める

シークレットスキャンは、ソースコードやコミット履歴の中に、APIキー・パスワード・トークン・秘密鍵といった機密情報が紛れ込んでいないかを検出します。OWASPのGuidelineが「まずリポジトリの認証情報漏えいの検査から始める」と位置づけている通り、DevSecOpsの最初の一手として最適です。理由は単純で、機密の漏えいは影響が即座かつ甚大で、しかも検出の仕組みが分かりやすく、導入の手間が小さいからです。

ここで最も重要な原理は、「一度コミットされた機密は履歴に残り続ける」という点です。誤ってキーをコミットし、次のコミットでファイルから削除しても、git の履歴をたどればその値は読み出せます。したがって対応は「ファイルを直す」では不十分で、漏れた認証情報そのものを無効化・ローテーション(再発行)することが必須です。スキャンはあくまで気づくための仕組みであり、気づいた後の鍵の失効までをセットで運用設計してください。

検出はコミット前(pre-commit フック)とCIの両方で行うのが理想です。pre-commit で開発者の手元で止められれば、そもそもリポジトリに入れずに済みます。ただしフックは各自の環境に依存し、すり抜けも起きるため、CI側でも必ず再検査して二重で守ります。なお、シークレットスキャンは「機密らしき文字列」を見つけるだけで、それが本物の有効なキーか、すでに無効化された値かまでは判定できません。検出後の確認と失効は人の判断が必要です。

ヒント

誤ってコミットした機密は、まず「その鍵を即座に無効化して再発行する」を最優先にしてください。履歴からの完全削除は手間がかかり、削除できても既に第三者が取得している可能性は消えません。失効させてしまえば、残った文字列はただの無効な値になります。

どの順番で、どこまで厳しくするか

4つのチェックを一度に全部入れ、すべてを「失敗したらビルドを止める」設定にすると、初期のノイズで開発が停止し、現場が機能を無効化して終わります。これは導入失敗の典型です。効果と導入容易性のバランスから、現実的な順序は次の通りです。判定根拠が明確で着手が軽いシークレットスキャンとSCAを先に入れ、ノイズ対処の運用に慣れてからSAST、最後にDASTという流れです。

段階入れるものこの段階のゴール
第1段階シークレットスキャン機密の混入を入口で止め、失効運用を確立する
第2段階SCA既知の脆弱性を持つ依存を可視化し、更新を習慣化する
第3段階SASTコードの危険なパターンを早期に検出する(重大度で絞る)
第4段階DAST仕上げに実際に攻撃が通るかを確認する(頻度を分ける)

「ビルドを止めるかどうか」の線引きも重要です。原則は、誤検知が少なく判定根拠が明確なものほど厳しく(失敗にして)よく、曖昧で大量に出るものほど最初は警告にとどめる、です。具体的には、シークレットの新規検出やSCAの重大な既知脆弱性は止める価値が高く、SASTは新規増加分の高重大度に限って止め、既存分はベースライン化する。DASTは時間がかかるため、ブロッキングにせず別パイプラインで回し、重大なものだけ通知するところから始めると無理がありません。

これらの考え方は特定ツールに依存しません。NISTのSSDF(SP 800-218)も、ツールやチェックの自動化を、組織として準備し(PO)・ソフトウェアを保護し(PS)・安全なソフトウェアを作り(PW)・脆弱性に対応する(RV)という4つの枠組みの中の手段として位置づけています。重要なのは個々のツール名より、「早く・自動で・低ノイズで・止めどころを設計して」回す体制を作ることです。日本語で原理から押さえたい場合は、IPAの「安全なウェブサイトの作り方」が代表的な脆弱性とその根本対策の良い土台になります。

導入順序の考え方は、OWASP DevSecOps Guidelineの「できるだけ早く検知し、認証情報の漏えい検査から段階的に組み込む」という方針を参考にしています。

よくある質問

SASTとDASTはどちらかで十分ですか?
役割が違うため、片方では不十分です。SASTはコード全体を網羅的に見ますが実際に攻撃が通るかは判断できず、DASTは実際に通るかを示せますが外から触れる範囲しか見られません。互いの弱点を補完する関係なので、可能なら両方を段階的に入れます。
誤検知が多くて運用が回りません。どうすれば?
全件を即対応・即ブロックにしないことが鍵です。重大度で絞り、確認済みで問題なしと判断したものは記録を残して抑制(ベースライン化)し、新規に増えた指摘に集中します。判定根拠が明確なチェック(シークレット・SCA)から厳格にし、曖昧なものは警告から始めます。
誤って機密をコミットしました。ファイルを消せば大丈夫ですか?
不十分です。git の履歴に値が残るため、まずその認証情報を無効化して再発行(ローテーション)してください。履歴からの削除も行いますが、既に取得された可能性は消えないので、失効が最優先です。
小規模なチームでも全部必要ですか?
最初から全部は不要です。導入が容易で効果の大きいシークレットスキャンとSCAから始め、運用に慣れてからSAST、最後にDASTと積み上げれば、小規模でも無理なく回せます。
DevSecOpsはツールを買えば実現できますか?
ツールは手段の一つにすぎません。本質は『早く・自動で・低ノイズで・止めどころを設計して』チェックを開発フローに組み込む体制づくりです。誰がいつ何を確認し、検出後にどう対応するかの運用設計が伴って初めて機能します。

まとめ

CI/CDにセキュリティを組み込むための確認

  • シークレットスキャンを入れ、検出時は鍵の失効・再発行まで運用化しているか
  • SCAで依存の既知脆弱性を可視化し、SBOMを持って小さく頻繁に更新しているか
  • SASTは重大度で絞り、確認済みはベースライン化して新規分に集中しているか
  • DASTは許可された検証環境のみで、頻度を分けて実行しているか
  • ビルドを止める/止めないの線引きを、判定根拠の明確さで設計しているか
  • 早期検知を強化したうえで、すり抜けを捉える運用監視も維持しているか

DevSecOpsは、特別な技術を導入することではなく、セキュリティ確認の「タイミングと回し方」を組み替えることです。SAST・DAST・SCA・シークレットスキャンはそれぞれ見えるものが違い、互いを補い合います。一度に完璧を目指さず、効果が大きく導入しやすいものから、ノイズへの対処と止めどころの設計をセットで積み上げていくのが、結局いちばん早く現場に根づきます。リスクの全体像をチームの共通言語にするには

もあわせてご覧ください。

出典・参考

この記事をシェア

関連する記事