CAMPFIRE 2026年 個人のサーバーに置いたGitHubの認証情報から社内のクラウドへ
従業員が発行した GitHub の認証情報が、個人開発のサーバーに意図せず上がり、第三者に使われた。攻撃者はリポジトリで読めた情報から社内業務のクラウドの認証情報を探し出し、その管理領域に入った。認証情報が会社の管理する場所の外にあり、1つで広く届いたことが、2段の侵入を1本の道にした。
要点
- 漏えいのおそれがあるのは、重複を除いて22万5,846件。プロジェクトオーナー、返金を受けた支援者、パートナーなどの氏名、住所、電話番号、メールアドレス、口座情報を含む。クレジットカードの情報は含まない。
- 起点は、従業員が発行した GitHub の認証情報が、従業員の個人開発のサーバーに意図せず上がったこと。
- 攻撃者は GitHub で読めた情報から社内業務のクラウドの認証情報を探して取り、その一部の管理領域に入った。GitHub の検知は4月3日、クラウドの検知は4月20日。
- フォレンジック調査では、認証情報と API キー、個人情報を含まないデータファイル、テーブル名と構成情報が取られた。一部のログが無く、閲覧の可能性は否定できなかった。
- 根本の直しは、認証情報を会社の管理下だけに置き、1つで広く届かないようにすること。会社自身もそう総括している。
何が起きたか
| 日付 | 発表の内容 |
|---|---|
| 時期の記載なし | 従業員が発行した GitHub の認証情報が、従業員が個人開発で使っていたサーバーに意図せず上がり、第三者に使われた[1] |
| 2026年4月2日夜から3日未明 | システム管理用の GitHub アカウントの一部のリポジトリで不審な操作を検知。対象アカウントを遮断し、関連アカウントを組織から外し、取られた可能性のある認証情報を差し替えた。第一報は4月2日22時50分頃に判明、調査結果は4月3日未明に検知と書く[1][2] |
| 4月3日 | アカウント全体の認証情報の調査と差し替え、主要なリポジトリの脆弱性の診断、監視の強化。第一報を公表[1] |
| 4月6日 | 優先度の高いコードの脆弱性の修正を完了し、権限の強いシステムユーザーの権限を整えた[1] |
| 4月7日 | GitHub の認証情報が漏れた原因を特定[1] |
| 4月14日 | GitHub で読めた情報を特定し第二報。開発業務の従事者413名の氏名とメールアドレスなどが読める状態だった。個人情報保護委員会へ報告[1][3] |
| 4月20日 | 社内業務で使うクラウド環境で不正アクセスを検知。不正に使われたアカウントとクラウドのリソースを止め、無効にした[1] |
| 4月21日から27日 | 外部専門機関へ支援を要請。顧客情報を管理するシステムの一部に不正アクセスの痕跡があるとの第三報、影響の範囲を特定した第四報と第五報を公表[1][4] |
| 5月30日 | 外部専門機関のフォレンジック調査が完了[1] |
| 6月2日 | 調査結果と再発防止策を公表[1] |
| 対象 | 項目 | 件数 |
|---|---|---|
| 2026年4月9日までの一部のプロジェクトオーナーとコミュニティオーナー | 氏名、住所、電話番号、メールアドレス、口座情報 | 108,784件、うち口座情報あり53,869件 |
| PayPal 決済、こんど払い、口座送金で返金を受けた過去の支援者 | 同上 | 118,010件、うち口座情報あり4,307件 |
| 2025年3月5日までに登録したパートナー | 氏名 | 1,282件 |
| 2020年にマイページの口座情報を編集した、区分の分からない人 | 口座情報 | 10,521件 |
| 重複を除いた計 | 225,846件 |
件数は6月2日の調査結果による[1]。クレジットカードの情報は含まれない。提供中のサービスは侵入されたクラウド環境と別の環境で動いており、サービスの基盤への不正な利用や改ざんは確認されていない[1]。
通った道筋
調査結果の言葉では、従業員が発行した GitHub の認証情報が個人開発のサーバーに意図せず上がって第三者に使われ、その後、攻撃者は GitHub で読めた情報をもとに、社内業務のクラウド環境に関わる認証情報を探して取り、その一部の管理領域に入った[1]。会社は、その認証情報は本来、会社の管理下の環境だけで扱い、要る最小の権限に限るべきものだったとし、認証情報の管理と権限の設計の仕組みと運用が足りなかったと書く[1]。
フォレンジック調査で確かめられたのは、クラウドに置かれた認証情報と API キー、個人情報を含まない一部のデータファイル、テーブル名と構成情報が取られたこと、探す途中で個人情報を含む1件がクエリの結果に出たことである。個人情報を含むファイルを外へ送った痕跡は無く、調査機関は攻撃の目的を認証情報の取得と見た。一方、会社は一部でログが取られておらず操作を直接確かめられない領域が残るため、閲覧の可能性を否定できないと判断した[1]。
認証情報の種類は発表に無い。完了した対策に、個人用アクセストークンへの依存を見直し、権限を限った認証方式へ移したことが挙がっている[1]。
形としては、2つの認証情報が鎖になっている。1つ目は会社の外に置かれた GitHub の認証情報で、2つ目は GitHub で読めた情報をもとに探し出されたクラウドの認証情報である。クラウドの認証情報そのものがリポジトリにあったのか、リポジトリの情報を手がかりに別の場所で見つけたのかは、発表に無い。どちらにしても、リポジトリを読めることが次の鍵への道になった。リポジトリに置いた秘密の値は、リポジトリを読める者すべてに渡り、ソースへの直書きは CWE-798 にあたる[10]。
悪い例。架空のリポジトリにある運用の設定
# ops/cloud.env 架空の例。値も本物ではない
CLOUD_PROJECT=internal-tools
CLOUD_ADMIN_KEY_ID=EXAMPLEKEYID0000
CLOUD_ADMIN_SECRET=example-secret-not-real-0000
直した例。リポジトリには役割の名前だけを置き、CIは実行のたびに短命の資格情報を得る
# .github/workflows/deploy.yml 架空の例
permissions:
contents: read
id-token: write # OIDC のトークンを得て、クラウドの役割と引き換える
env:
CLOUD_ROLE: internal-tools-deployer # 鍵ではなく、絞った役割の名前
直した形では、リポジトリと GitHub の認証情報が取られても、得られるのは役割の名前だけで、クラウドの管理領域の鍵は手に入らない。CIの置き場所と OIDC の扱いは 秘密の鍵の扱い の置き場所の節にある。
どこで止められたか
| 段 | この件で発表されたこと | 止める仕組み |
|---|---|---|
| 1 発行 | 従業員が GitHub の認証情報を発行した。対策として個人用アクセストークンへの依存を見直した[1] | 組織で classic の個人用アクセストークンを拒み、fine-grained の個人用アクセストークンを承認制にし、期限の上限を決める[6] |
| 2 外に置く | 個人開発のサーバーに意図せず上がった[1] | 業務の認証情報は会社の管理する環境だけで使う。個人の開発と業務の資格情報を同じ機械で混ぜない |
| 3 次の鍵 | GitHub で読めた情報から、クラウドに関わる認証情報を探して取った[1] | リポジトリに秘密の値を置かない。非公開のリポジトリでも secret scanning を有効にする[7] |
| 4 届く | クラウドの一部の管理領域に入られた。本来は要る最小の権限に限るべきだった[1] | 認証情報ごとに権限を最小にし、管理の操作は別の主体と別の認証にする[8] |
| 5 残らない | 一部のログが取られておらず、閲覧の可能性を否定できなかった[1] | クラウドの管理の操作とデータの読み取りの監査ログを全域で取り、高リスクの操作で警告する |
1 発行。組織が鍵を把握する
GitHub の個人用アクセストークンは、利用者が自分で作る。classic のトークンは、その利用者が触れるすべてのリポジトリに届く。fine-grained のトークンは、1つの利用者か組織に限られ、特定のリポジトリにさらに絞れる。GitHub は可能なら fine-grained を使うよう勧める[5]。組織の所有者は、classic のトークンが組織の資源に届くのを止められ、fine-grained のトークンを1つずつ承認制にでき、期限の上限を決められる。上限を決めても既にあるトークンは失効せず、上限に合わないものが組織に届かなくなる[6]。
これで、誰がどの範囲の鍵を持つかを組織の側で一覧でき、外に出たときに届く範囲も決まる。
2 外に置く。会社の管理下だけで扱う
会社自身が、認証情報は管理下の環境だけで扱うべきものだったと書く[1]。どう個人のサーバーに上がったか、そこから第三者がどう得たかは発表に無い。個人のサーバーは、会社の監視、検出、失効の手順が届かない。業務の鍵を個人の機械や個人の開発の設定に入れないこと、開発の機械では鍵のファイルを道具に読ませないことは、秘密の鍵の扱い の漏れる経路と置き場所にある。
3 次の鍵。リポジトリを読めた時点で秘密は漏れている
2段目の侵入は、GitHub で読めた情報からクラウドの認証情報にたどり着けたから成り立った[1]。リポジトリに秘密の値も、秘密の置き場所への道筋も残さないことが、この段の止めになる。非公開のリポジトリは、組織の中で読める者が多く、取られた1つの GitHub の認証情報で丸ごと読める。2026年11月時点の GitHub では、secret scanning は公開のリポジトリでは無料で自動だが、組織の非公開のリポジトリでは GitHub Secret Protection が要る[7]。
GitHub の認証情報が取られたと分かったら、その認証情報で読めたリポジトリの中の秘密の値もすべて漏れたものとして無効にする。GitHub の側の鍵を替えただけでは、取られた複製の中の鍵は生きている[9]。この件で、クラウドの認証情報がいつ取られ、いつ使われたかは発表に無い。
4 届く。1つで広く届かせない
会社は今後の方針に、認証情報1つで広い範囲を操作できないよう、権限の設計と認証方式を見直すと書く[1]。OWASP も、鍵には役目に要る最小の権限だけを付けるよう求める[8]。リポジトリで見つかる鍵がCIのデプロイ用だけなら、管理領域の認証情報や API キーの保管場所には届かない。静的な鍵とクラウドの公開の型は A02 セキュリティ設定の不備 の型3にある。
5 残らない。記録の穴
個人情報のファイルを外へ送った痕跡は無かったが、ログの無い領域が残ったため、会社は閲覧の可能性を否定できなかった[1]。どの主体が、どこから、何を読んだかが全域で残っていれば、範囲は絞れた。会社は完了した対策に、監査ログの取得と警告の通知の強化と、警告を確かめて対応するトリアージの体制を挙げる[1]。記録すべき出来事は A09 セキュリティログとアラートの不備 にある。
守り方
- 業務の認証情報は、会社の管理する環境の中だけで発行し、使う。個人の機械と個人の開発の環境に置かない[1]。秘密の鍵の扱い
- リポジトリにクラウドの認証情報を置かない。CIは OIDC で実行のたびに短命の資格情報を得て、長く使う鍵を持たない。
- 認証情報ごとに要る最小の権限を付け、クラウドの管理の操作は別の主体に分ける[8]。A02 セキュリティ設定の不備
- GitHub の組織で classic の個人用アクセストークンを止め、fine-grained を承認制にし、期限の上限を決める[6]。
- 非公開のリポジトリにも secret scanning と push protection を有効にし、自前の鍵の型を登録する[7]。
- GitHub の認証情報の漏れに気付いたら、その認証情報で読めたリポジトリ内の秘密もまとめて無効にし、差し替える[9]。
- クラウドの管理の操作とデータの読み取りの監査ログを全域で取り、高リスクの操作に警告を付け、確かめる人と手順を決める[1]。A09 セキュリティログとアラートの不備
- 社内業務の環境と、顧客へ出すサービスの環境を分ける。この件では、サービスは侵入された環境と別にあり、改ざんは確認されなかった[1]。
参照
- 不正アクセス事案にかかる調査結果について 株式会社CAMPFIRE、2026年6月2日
- GitHubアカウントへの不正アクセス発生に関するお知らせとお詫び 株式会社CAMPFIRE、2026年4月3日
- GitHubアカウントへの不正アクセス発生に関するお知らせとお詫び 第二報 株式会社CAMPFIRE、2026年4月14日
- GitHubアカウントへの不正アクセス発生に関するお知らせとお詫び 第三報 株式会社CAMPFIRE、2026年4月22日
- Managing your personal access tokens GitHub Docs
- Setting a personal access token policy for your organization GitHub Docs
- About secret scanning GitHub Docs
- Secrets Management Cheat Sheet OWASP Cheat Sheet Series
- Removing sensitive data from a repository GitHub Docs
- CWE-798 Use of Hard-coded Credentials MITRE