投稿

マネーフォワードGitHub流出事件を読み解く — なぜ起きたのか、どう防ぐか

マネーフォワードGitHub流出事件を読み解く — なぜ起きたのか、どう防ぐか

参考: マネーフォワードのGitHub不正アクセス事件をエンジニア視点で読み解く

まとめ

  • ソースコードへの認証情報ハードコードと本番データのテスト流用は「当時は正解だった判断」が組織の成長とともにアップデートされなかった結果
  • 削除済みファイルも git log -p で復元できる。リポジトリをクローンされると歴史ごと盗まれる
  • セキュリティ問題は「人の意識」ではなく「機械的ブロック」で防ぐ設計が必要
  • GitHub の Push Protection は無料で今日から有効化できる

事件の概要

2026年5月1日、マネーフォワードがGitHubへの不正アクセスを公表した。攻撃者は漏えいした認証情報でリポジトリをクローンし、ソースコード・個人情報・認証キーが流出した可能性がある。銀行口座連携機能は一時停止された。

流出した可能性のある内容:

  • カード保持者370件分の氏名(アルファベット)とカード番号下4桁
  • ソースコードにハードコードされた認証キー・パスワード
  • カード番号全桁、有効期限、CVV(未確認)

技術的な問題点

本番データをテストフィクスチャに使っていた

バグ報告で「本番でだけ起きる」ケースが続くと、エンジニアは「本番に近いデータが必要」と判断する。そこで本番ユーザーデータを仮名化せずそのままテスト環境に持ち込む、という判断が生まれる。

カード情報はPCI DSSの対象で、カード番号全桁の平文保存は原則禁止。下4桁は許容されているが、氏名と組み合わさると個人識別が可能になる。「下4桁だから大丈夫」という判断が盲点になりやすい。

マスキング基盤のデファクトスタンダードはまだ業界で確立されていない。小〜中規模なら Faker / Factory Boy でダミーデータを生成し本番を使わない設計が現実的。PCI DSS が関わる場合は「本番カードデータを開発環境に持ち込むこと自体を禁止する」が唯一の正解。

認証情報のハードコード

スタートアップ創業期は「まず動かす」が正解で、当時はそれが適切な判断だった可能性がある。問題はその後、組織が成長しても見直されなかったこと。

「リポジトリをクローンすれば動く」状態を維持するために環境変数管理やSecrets Manager連携を後回しにするのはよくある話で、ローカル開発のセットアップを楽にしたいという動機も理解できる。

Git履歴に残り続ける

ここが一番見落とされやすい。「ファイルを削除した」だけではGitの履歴から消えない。git log -p で過去のコミットから復元できる。リポジトリをクローンされると履歴ごと盗まれるため、発見したシークレットは即座に無効化する必要がある。


なぜ起きたのか — 背景の推測

「前からあるコード」はレビューされない

新規追加コードはレビューされるが、「昔からある」コードはレビューの対象になりにくい。技術的負債は可視化されないまま温存され続ける。

切り替えタイミングを判断するには、「何かのイベントを契機にする」のが現実的だ。

切り替えを正当化するイベント
新しい規制・標準が適用された
担当者の引き継ぎが発生した
インシデントが起きた
大規模リファクタリングの機会
定期セキュリティ監査(制度として)

最後の「定期セキュリティ監査の制度化」がなければ、他のイベントが起きるまで何年でも放置される。

セキュリティ部門が啓発しかできない構造

セキュリティ指摘が実装者に届いても、優先度の決定権はプロダクトオーナー側にある。

セキュリティ部門:「言ったけど直してもらえなかった」
開発チーム:「言われたけど優先度が下がった」

誰も悪意はないのに問題が温存される。セキュリティの価値は「何も起きない」ことで証明されるため、可視化が難しく評価もされにくい。

開発チームに「ついでにやれ」は構造的に無理

PdMもTLも上と下からの要求に挟まれている。メンバーは「言っても評価されない」「まず自分の担当を終わらせる」となる。これはモチベーションの問題ではなくインセンティブ設計の問題だ。


対策の優先順位

重要なのは「人の意識」より「機械的なブロック」を先に入れること。

今日からできる(無料)

GitHub の Push Protection を有効化する。シークレットらしき文字列が含まれるコミットをプッシュ時にブロックする。設定5分。今回の事件の一部はこれで防げた可能性がある。

次のステップ

  • pre-commit hook に gitleaks / TruffleHog → コミット時点でブロック
  • CI にシークレットスキャンを追加 → マージ前に全ファイルをスキャン
  • 既存リポジトリの全履歴をスキャン → 発見された鍵は即座に無効化

シークレット管理の移行

AWS Secrets Manager、GCP Secret Manager などに移行する。PAT(Personal Access Token)はOIDCベースの短期トークンに切り替える。有効期限が長い静的なシークレットを減らすことが目標。

セキュリティチームを作るなら

「啓発部門」のままにならないために、技術的にブロックする権限を持たせる。PRのマージ権限、CIパイプラインの設定変更権限など。権限なきセキュリティチームは看板を変えただけになる。


所感

悪意があったわけではない。「当時は正解だった判断」が組織の成長に合わせてアップデートされなかった、というのが本質だと思う。

そして「前からあるコード」をいつ見直すかの判断基準を持つのは難しく、外部からのプレッシャーがなければ何年でも放置される。技術的負債と同じで、「気づいてはいるけど手が回らない」状態は放置するほど直しにくくなる。まず機械的ブロックを一点だけ入れるところから始めるのが、組織の抵抗が少なく効果が出やすいアプローチだと感じた。

トレンドのタグ