2026 年 4 月末、Zenn Trending に 「マネーフォワードのGitHub不正アクセス事件をエンジニア視点で読み解く — なぜソースコードに本番カード情報と認証キーが入っていたのか」 が長期ランクインしました。プライベートリポジトリへの不正アクセスという入口の派手さに目が行きがちですが、本質は 「漏れたら一発アウトの情報がソースコードに直書きされていた」 という、受託開発の現場でも他人事ではない問題です。
弊社では受託で構築したシステムを引き渡す前後に 「シークレット監査(Secret Audit)」 を必ず実施しています。本記事では、マネーフォワード事件から抽出できる教訓を出発点に、受託で必ず押さえるべきリポジトリ運用標準、検査ツール、価格レンジまでを整理します。
なぜ「ソースコードに本番情報」が起きるのか
事件の技術的な詳細は前述の Zenn 記事に詳しいですが、受託の現場で同じ事故が起きるパターンは以下に集約されます。
| パターン | 典型例 | 受託での発生確率 |
|---|---|---|
| 開発者の “とりあえず” コミット | .env をうっかり git add | 高 |
| 環境別ファイルの取り違え | config.production.json が公開リポに残存 | 中 |
| テストデータが本番値 | テストカード番号として本物の番号を使用 | 中〜高 |
| サードパーティ SDK の認証情報 | Slack Webhook URL がハードコード | 高 |
| デバッグコードの残置 | console.log(JSON.stringify(secrets)) | 中 |
| Git 履歴の中だけに残るシークレット | 一度コミットして次のコミットで削除 | 高 |
特に Git 履歴の中だけに残るシークレットが厄介で、最新の HEAD だけを見るレビューでは絶対に発見できません。攻撃者が git log -p を 1 度走らせれば露呈するため、漏洩したリポジトリのアーカイブが流通した時点で詰む構造です。
マネーフォワード事件から抽出できる 4 つの教訓
事件の対応公表内容と外部解説を踏まえると、受託開発に持ち込めるべき教訓は次の 4 つに整理できます。
教訓 1: シークレットは「絶対に Git に置かない」を物理で担保する
ヒューマンエラーは必ず起きるため、「人がうっかりコミットしても Git に届かない」仕組みで守ります。具体的には以下の 3 段重ね:
- pre-commit フック(gitleaks / trufflehog)で commit 前にブロック
- GitHub Push Protection(GitHub Advanced Security)で push 前にブロック
- CI でのフルスキャンで main ブランチへの混入をブロック
教訓 2: 本番カード情報・本人確認情報は “システム外” に置く
決済・本人確認系のデータは、自社システムに保管しないアーキテクチャが王道です。Stripe / GMO / Square などのトークン化を経由し、機微情報は決済プロバイダに置きっぱなしにします。受託で「カード番号を DB に持つ」要件が来たら、まずトークン化で済まないかを設計レビューで覆すのが第一歩です。
教訓 3: リポジトリの “アクセスログ” を見る運用を設ける
GitHub プライベートリポジトリへの不正アクセスは、ログ上は 「正規アカウントからの通常アクセス」として記録されます。検知するには、Audit Log の異常値(深夜・国外 IP・短時間大量 clone)に対するアラートを仕込むしかありません。GitHub Enterprise の Audit Log Streaming + SIEM が標準解です。
教訓 4: インシデント対応の “最初の 30 分” を訓練する
事件発生時、最初の 30 分の動きが被害規模を決めるのは常識化しています。受託で構築したシステムでも、引き渡し時に 「シークレット漏洩疑い時の初動マニュアル(30 分版)」を必ず添付しておくべきです。これは GitHub コードセキュリティ・リスクアセスメント で扱った “リポジトリ全体のセキュリティ評価” の初動編に当たります。
受託で必ず実施するシークレット監査の手順
弊社で受託案件の引き渡し前後に実施している、シークレット監査の標準手順を公開します。
[Phase 1] HEAD スキャン(1〜2 時間)
├─ gitleaks detect --source . -v
├─ trufflehog filesystem . --json > truffle-head.json
└─ 検出されたシークレットを台帳に記録
[Phase 2] Git 全履歴スキャン(2〜6 時間、リポジトリ規模次第)
├─ trufflehog git file://. --json > truffle-history.json
├─ git log -p で目視確認すべきコミット範囲を特定
└─ 過去にコミットされて削除済みのシークレットも漏れなく拾う
[Phase 3] 検出シークレットの "生死判定"(1〜2 日)
├─ AWS / GCP / Stripe など発行元 API で当該キーが有効か確認
├─ 有効なら即時失効依頼 + 顧客報告
└─ 失効済みでも台帳化(再発防止策の根拠資料)
[Phase 4] 履歴クリーニング(必要時、半日〜2 日)
├─ git filter-repo / BFG Repo-Cleaner で履歴から除去
├─ 全コラボレーターに force-push 後の手順を周知
└─ 旧クローンの破棄を顧客側に依頼
[Phase 5] 再発防止策の実装(1〜3 日)
├─ pre-commit + Push Protection + CI スキャンの 3 段重ね
├─ シークレット管理基盤(AWS Secrets Manager / GCP Secret Manager / Vault)
└─ ランブック(漏洩疑い時 30 分初動)の納品
ポイントは Phase 3 の “生死判定” です。Git 履歴に残っていても 既に失効済みなら被害ゼロですが、失効していないキーが履歴に眠っていると、リポジトリが過去に流出していた場合に 今日この瞬間にも悪用されている可能性があります。「とりあえず履歴から消す」より、「まず生きているかを確認する」が優先順位です。
受託で標準化したい “シークレット運用 5 項目”
受託の引き渡し時に顧客と握っておくべき、シークレット運用の 5 項目を整理します。
| 項目 | 標準ルール | 重要度 |
|---|---|---|
| シークレット保管場所 | AWS Secrets Manager / GCP Secret Manager / Vault に集約 | ★★★ |
.env のリポジトリ外管理 | .gitignore 強制 + .env.example のみコミット | ★★★ |
| pre-commit フック | gitleaks + 拒否設定の zip を make setup で配布 | ★★★ |
| ローテーション周期 | API キー: 90 日、長期キー: 365 日 | ★★ |
| 漏洩疑い時のランブック | ”誰が・何を・何分以内に” を A4 1 枚で常備 | ★★ |
特に .env.example のみコミット ルールは強力で、新規参画メンバーが .env を作る手順が明文化される副次効果もあります。これは Hashicorp Vault 2 によるエージェント時代のシークレット管理 で扱った “シークレット集中管理” の基本動作に当たります。
検査ツール比較 — 受託で実用的な選択肢
シークレット検出ツールは多数ありますが、受託の現場で使い勝手が良いものを比較します。
| ツール | 強み | 弱み | 受託での向き |
|---|---|---|---|
| gitleaks | OSS、設定が簡単、pre-commit との相性が良い | 検出ルールは正規表現ベース | 標準採用 |
| trufflehog | 検証機能(キーが生きているか確認)が強い | 履歴スキャンが遅い | 引き渡し前監査 |
| GitHub Secret Scanning | 主要プロバイダのキーを GitHub 側で自動検出 | プッシュ後に検知(push protection は GHAS のみ) | 平常運用 |
| Snyk Code | 商用、シークレット + コード脆弱性を統合 | ライセンスが必要 | 大規模・継続監査 |
| Detect-Secrets(Yelp) | ベースライン管理が秀逸、誤検知の “認識” が可能 | UI なし | CI 組み込み |
弊社の標準は gitleaks(pre-commit)+ trufflehog(引き渡し時)+ GitHub Secret Scanning(運用) の 3 層で、まずこの構成を提案するケースが多いです。
受託パッケージの価格レンジ
弊社で「シークレット監査 + 再発防止策実装」を受託メニューとして提供する際の価格レンジです。
| パッケージ | 期間 | 価格レンジ | 主成果物 |
|---|---|---|---|
| シークレット緊急監査 | 3〜5 日 | 60〜120 万円 | 監査レポート + 緊急対応 |
| 監査 + 再発防止策実装 | 3〜4 週 | 200〜400 万円 | 上記 + pre-commit / CI 統合 + ランブック |
| 全社リポジトリ棚卸し | 8〜12 週 | 500〜1,200 万円 | 全リポ監査 + 集中管理基盤構築 |
| 月次セキュリティ運用 | 月額 | 30〜80 万円/月 | 月次スキャン + ローテーション支援 |
「インシデントが起きてからの緊急監査」と「平時の予防監査」では費用対効果が桁違いに違います。引き渡し時の予防監査は、平均的な受託案件のごく一部の予算で実施できる一方、漏洩発覚後の緊急対応は、調査・通知・行政対応で数千万〜億単位のコストになるのが現実です。
引き渡しチェックリスト — 受託でそのまま使える 12 項目
最後に、受託案件の引き渡し時にそのまま使えるチェックリストを置いておきます。
-
gitleaks detectが main 全コミットでクリーン -
trufflehog git file://.が全履歴でクリーン(または既知の失効済みのみ) -
.env/.env.local等が.gitignoreに含まれている -
.env.exampleがコミットされており、必要キー一覧が明示 - 全シークレットが Secrets Manager / Vault 等に集約されている
- pre-commit フックが配布パッケージに同梱
- CI でシークレットスキャンが必須チェックになっている
- GitHub Push Protection が有効(GHAS 契約あれば)
- Audit Log Streaming + アラート設定が稼働
- 漏洩疑い時の初動ランブックが納品物に含まれる
- API キーのローテーション周期が文書化されている
- 引き渡し後 90 日のサポート条件が SOW に明記
これは 既存 API を MCP サーバー化する設計パターン や AI エージェント本番DB削除ガードレール で書いた “ガードレール思想” の データ層版 に当たります。AI エージェント時代は、人だけでなくエージェントも誤って commit する可能性を前提に、機械側で物理ブロックする設計が一段重要になりました。
まとめ — 「事故が起きてからの対応」より「事故を起こさない設計」を受託に組み込む
マネーフォワード事件は、Git の利便性を当然視してきた業界全体への警鐘でした。受託で構築したシステムが顧客の信頼を毀損する原因にならないために、引き渡し前後の シークレット監査を標準工程に組み込む のが、受託側の責任範囲だと弊社は考えています。
弊社では、新規受託の引き渡し時の監査だけでなく、「過去に納品した既存システムの遡及監査」もパッケージで提供しています。「既存リポジトリのシークレット混入を一度棚卸ししたい」「受託先と一緒に再発防止策を作り直したい」というご相談は お問い合わせフォーム からお気軽にどうぞ。