シフトレフトセキュリティ

セキュリティ対策を開発ライフサイクルの早い段階 (左側) に組み込むアプローチ

セキュリティDevOps

シフトレフトセキュリティとは

シフトレフトセキュリティは、セキュリティ対策を開発ライフサイクルの後工程 (デプロイ後の脆弱性スキャン) ではなく、早い段階 (設計、コーディング、CI) に組み込むアプローチである。「左」は開発タイムラインの早い段階を指す。

ソフトウェア工学では、バグの発見が後工程になるほど修正コストが大きく膨らむという経験則が古くから知られている (定量的な倍率には諸説ある)。セキュリティの脆弱性でこれが効くのは、後工程で見つかるほど直し方の選択肢が減るためである。設計段階なら認証の置き方そのものを変えられるが、リリース後に同じ問題が出れば、既存の呼び出し元との互換性を保ったまま塞ぐしかなく、影響調査と再テストの範囲も一緒に広がる。

従来:  設計 → 実装 → テスト → デプロイ → [セキュリティ監査]
                                            ↑ 発見が遅い、修正コスト大

シフトレフト: [脅威モデリング][SAST][SCA] → テスト → デプロイ
              ↑ 早期発見、修正コスト小

各段階でのセキュリティ施策

注意したいのは、左に寄せれば右をやめられるわけではない、という点である。段階ごとに手に入る情報が違うため、その時点で判定できる問題の種類も違う。依存ライブラリの脆弱性はロックファイルが確定して初めて特定でき、設定ミスはテンプレートが書かれて初めて見える。施策は「後工程から前工程へ移す」より「各段階に、その時点で判定できるものを置く」と考えるほうが実装しやすい。

段階施策内容ツール例
設計脅威モデリング攻撃者の視点でシステムの脅威を洗い出すSTRIDE
コーディングIDE プラグインコード記述中にリアルタイムで脆弱性を検出ESLint security rules
プリコミットシークレットスキャンコミット前に API キーやパスワードの混入を検出git-secrets
CISAST (静的解析)ソースコードの脆弱性パターンを検出Semgrep, CodeQL
CISCA (依存関係)npm パッケージの既知の脆弱性を検出npm audit, Snyk
CIIaC スキャンテンプレートの記述誤りと危険な設定を検出 (cfn-lint は構文・仕様適合の検査であり、セキュリティポリシーの検査は Checkov 側が担う)cfn-lint, Checkov
デプロイコンテナスキャンコンテナイメージの脆弱性を検出Trivy, ECR スキャン

SAST と SCA の違い

混同されやすいが、検査対象が異なる。

種類検査対象検出する問題
SAST自分が書いたコードSQL インジェクション、XSS、ハードコードされた認証情報query("SELECT * FROM users WHERE id = " + userId)
SCA依存ライブラリ既知の CVE (脆弱性)lodash 4.17.19 以前の Prototype Pollution (CVE-2020-8203・4.17.20 で修正)

両方を CI に組み込むことで、自前のコードと依存ライブラリの両方をカバーする。

CI パイプラインへの組み込み

CI から見たセキュリティツールは、要するに「終了コードを返すコマンド」である。どの条件で非ゼロを返すかはツールごとに違うため、そこを揃えないと「落ちてほしいのに通る」「通したいのに落ちる」の両方が起きる。

# GitHub Actions の例 (SAST は job 側で container: image: semgrep/semgrep を指定して実行)
- name: npm audit
  run: npm audit --omit=dev --audit-level=high  # high 以上が 1 件でもあれば非ゼロ終了

- name: SAST
  run: semgrep ci  # Semgrep CE 単体で回すなら semgrep scan --config p/owasp-top-ten

- name: IaC scan
  run: npx cfn-lint template.yaml && checkov -f template.yaml --framework cloudformation

npm audit--audit-level は「非ゼロ終了させる最低の深刻度」の指定であり、high を渡すと high と critical だけがビルドを止める。開発時にしか使わない依存の脆弱性でリリースを止めても打ち手が無いことが多いため、--omit=dev で対象を絞るかどうかは導入時に決めておく。Semgrep 側は、2026 年 8 月時点の公式 CI 設定例が semgrep/semgrep コンテナ内で semgrep ci を実行する形になっており、以前広く使われていたアクション形式 (returntocorp/semgrep-action) は公式リポジトリ上で非推奨と告知されている。CI 設定は他プロジェクトからコピーされて長く生き残るため、参照しているアクションがまだ保守されているかを定期的に確認する。

全ての警告をブロッカーにすると開発速度が低下する。実務では以下の段階的な運用が現実的だ。

重大度CI での扱い理由
Criticalビルド失敗 (ブロック)リモートコード実行など即座に悪用される
Highビルド失敗 (ブロック)データ漏洩のリスクが高い
Medium警告 (ノンブロック)悪用条件が限定的
Lowレポートのみ情報提供レベル

この表は新規プロジェクトで最初から入れる場合の姿である。既存プロジェクトに後から入れると初回スキャンで数百件が出るのが普通で、そのままブロックにすると誰も CI を通せなくなる。Checkov の --soft-fail (検査は走るが常に終了コード 0) のように結果だけを出すモードでまず棚卸しし、既存分を例外として登録してからブロックへ切り替える。以後は「新たに増えた分だけを止める」運用になり、この形にすると定着しやすい。

SAM / CloudFormation でのシフトレフト

IaC のセキュリティスキャンは、インフラの設定ミスを本番デプロイ前に検出する。

  • S3 バケットのパブリックアクセスが有効になっていないか
  • Lambda 関数に過剰な IAM 権限が付与されていないか
  • DynamoDB テーブルの暗号化が有効になっているか
  • API Gateway に認証が設定されているか
# cfn-lint: テンプレートが仕様どおり書けているかを検査 (セキュリティ検査ではない)
cfn-lint template.yaml

# Checkov: 危険な設定をポリシーとして検査 (-f は単一ファイル・-d はディレクトリ)
checkov -f template.yaml --framework cloudformation

よくある失敗パターン

ツールを入れただけで満足する

SAST ツールを CI に組み込んでも、検出結果を誰も確認しなければ意味がない。検出された脆弱性のトリアージと修正のプロセスを定義し、担当者を明確にする。

偽陽性の放置

SAST は偽陽性 (実際には脆弱性でない検出) が多い。偽陽性を放置すると、開発者が警告を無視する習慣がつき、本物の脆弱性も見逃す。偽陽性は明示的に抑制し、その理由をコメントに残す。抑制コメントは該当行か直前の行に置く。素の // nosemgrep はその箇所で全ルールを黙らせてしまうため、// nosemgrep: <名前空間付きのルール ID> の形で対象を 1 つに絞る。Semgrep では抑制しても検出自体は無視扱いの記録として残るので、後から抑制の棚卸しができる。

導入の成否をどこで見るか

シフトレフトが失敗するときの共通点は、検出件数を増やすこと自体が目標になってしまうことである。見るべき指標は検出件数ではなく、開発者がレビューに出す前に自分の変更のどこが問題かを自分で把握できる状態になったか、である。この観点で見ると、CI が落ちた理由をログから読み解けないツールや、修正方法を示さないツールは、前工程に置いても後工程の人手を増やすだけに終わる。ツール選定では検出精度と同じ重みで「開発者に何を返すか」を確かめておきたい。

この記事は役に立ちましたか?

関連用語

関連する記事