Upgrade to Pro — share decks privately, control downloads, hide ads and more …

サプライチェーン攻撃対策「層を重ねて落ちない壁」を10日間で組み上げた話 #TechLeadC...

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

サプライチェーン攻撃対策「層を重ねて落ちない壁」を10日間で組み上げた話 #TechLeadConf2026

Avatar for Kashun Yoshida

Kashun Yoshida

May 11, 2026

More Decks by Kashun Yoshida

Other Decks in Programming

Transcript

  1. 問題提起 — どの時点で止められるか 2026-03-19、Trivy の公式 Docker イメージが乗っ取られた 週 1 億

    DL の axios も同月に postinstall 悪用攻撃 既存の備え: Trivy(2022年〜運用)+ dependabot → 「公開後に CVE 登録された脆弱性」を検出する仕組みは揃っていた 不足していた層: 悪性パッケージが開発環境 / CI に降りてくる前に遮断する仕組み axios 系 postinstall 攻撃は CVE 登録前に発火 Trivy 自身の Docker イメージ汚染は docker pull 時にコードが実行 ※ Trivy = Aqua Security 製の OSS 脆弱性スキャナ。Docker イメージや依存関係を CVE データベースと突合する 2 / 7
  2. Layer 1-2 — 即時遮断 + 取り込みを7日遅延 Layer 1: レジストリプロキシで即時遮断 Takumi

    Guard(GMO Flatt Security 製、pypi.flatt.tech / npm.flatt.tech) → 悪性パッケージを 403 で遮断 / PyPI は 72h 検疫期間つき Layer 2: 時間ベース防御(クールダウン) 対象 ツール 設定 Python uv exclude-newer = "1 week" Node.js pnpm minimumReleaseAge: 10080 (= 7日) GitHub Actions dependabot cooldown.default-days = 30 GitHub Actions pinact --min-age 7 責務: 公開直後の悪性パッケージの取り込みを 一定期間遅延させる ※ pip → uv 移行も 10日間に含む(Layer 2 + 3 を 1 ツールで担保するため) 3 / 7
  3. Layer 3-4 — ハッシュ検証 + パッケージマネージャーのセキュリテ ィ機能 Layer 3: ロックファイル

    + ハッシュ検証 uv.lock / pnpm-lock.yaml に SHA256 を自動記録・検証 CI: uv sync --frozen / pnpm install --frozen-lockfile Layer 4: pnpm v10 のセキュリティ機能 # pnpm-workspace.yaml blockExoticSubdeps: true # git URL / tarball 経由の間接依存を遮断 trustPolicy: no-downgrade # provenance ダウングレード検出 # ← axios 攻撃はこれで防げていた # postinstall スクリプトは v10 でデフォルト無効化 責務: 正規パッケージの乗っ取り / 間接依存への注入を検出 4 / 7
  4. Layer 5-6 — Actions SHA ピン + 脆弱性スキャン Layer 5:

    SHA ピン + 静的検査3点セット ツール 責務 pinact @v6 等のタグ → commit SHA に自動ピン actionlint 構文・型チェック ghalint セキュリティポリシー(permissions 最小化 等) zizmor 脆弱性(template injection 等) Layer 6: 脆弱性スキャン dependabot(GitHub Advisory DB)+ Trivy(Docker イメージ) 責務: ワークフロー自体の改ざんを遮断 / 既知 CVE を継続検出 5 / 7
  5. 設計の試練 — trustPolicy 有効化で pnpm updateがコケた trustPolicy: no-downgrade (公開日順の provenance

    低下を検査)を有効化 → pnpm update が失敗する。 判断軸: 攻撃か false positive か パッケージ 原因 [email protected] 上流 CI/CD 停止で provenance 欠落。 ~6.21.0 制約で復旧版 6.23.0+ に上げられない [email protected] v6 は全バージョン provenance なし、v7 は @babel 非対応 @swc/[email protected] 復旧版あり、lockfile に残存 着地: 3件とも trustPolicyExclude で個別除外(理由コメント必須) 学び: 設計通り動いたからこそ浮上した false positive 6 / 7
  6. まとめ — 6層の責務 Layer 責務 L1 レジストリプロキシ 既知の悪性を即遮断 L2 クールダウン

    未知の悪性の取り込みを遅延 L3 ロック + ハッシュ 改ざん検出 L4 PM セキュリティ機能 乗っ取り / 間接依存 / postinstall L5 Actions SHA ピン ワークフローの改ざん遮断 L6 脆弱性スキャン 既知 CVE を継続検出 攻撃ベクトルが違えば、止める層も違う。 だから 6 層に分けて、責務ごとに受け止める。 →AIを含めたチームが活用しやすい仕組みづくり 7 / 7