事故図鑑
Codecov 改ざん事件(2021)— CIの“信頼するツール”が乗っ取られ秘密情報が流出した原因と防御
2021年、開発ツール Codecov の「Bash Uploader」(CIで curl|bash で実行されるスクリプト)が上流で改ざんされ、約2か月にわたり利用企業のCI環境から秘密情報(APIキー・トークン・認証情報)が外部へ送られていました。気づけたのは1社のチェックサム照合。HashiCorpやTwilioなど二次被害も発生。サプライチェーン攻撃の連鎖を防御の地図として分解し、あなたのCIで同じ轍を踏まないための具体策(取得物の完全性検証・CI秘密の最小権限・ローテーション・egress監視)を、公開記録の事実だけで解説します。
実際に起きた公開事故を、ニュースの再放送ではなく 「あなたの環境でどう防ぐか」 の視点で読み解きます。本記事は 公開記録(公式ポストモーテム・CISA・セキュリティ企業の分析)にもとづく解説です。出典は末尾に明記します。
- 対象
- Codecov(コードカバレッジ計測ツール)と、その利用企業のCI
- 公表
- 2021年4月15日(改ざん 1月31日〜/発覚 4月1日)
- 手口分類
- サプライチェーン攻撃(信頼された配布物の上流改ざん)+CI秘密情報の窃取
- 影響規模
- Codecovの多数の顧客(最大約29,000)。HashiCorp・Twilio・Rapid7等で二次被害
- 根本原因
- CIが取得物を未検証で実行 + 配布元の鍵管理不備 + CI秘密の過剰露出
- 本命の対策
- 取得物の完全性検証・CI秘密の最小権限・ローテーション・egress監視
何が起きたか(平易に)
多くの開発チームは、テストの自動実行環境(CI)で外部ツールを curl … | bash のように取ってきてそのまま実行します。Codecov の Bash Uploader もそうしたスクリプトでした。
攻撃者は、Codecov 側の配布の仕組みの不備を突いて配布されるスクリプト本体を書き換え、CIで実行されると その環境にある環境変数(秘密情報)を外部のサーバーへ送るように仕込みました。利用企業から見れば、いつも通り信頼するツールを呼んだだけ。自分のコードは1行も変わっていないので、異常に気づく手がかりがほぼありません。
約2か月後、ある利用企業がスクリプトの チェックサム(SHA256)を公式の値と照合し、食い違いを発見。ここでようやく改ざんが露見しました。流出しうった情報には、クラウドのキー・デプロイ鍵・APIキー・トークンなどが含まれ、そこから HashiCorp や Twilio など他社への二次被害に連鎖しました。
“自分のコードが無傷”だから怖い
サプライチェーン攻撃は、あなたの書いたコードではなくあなたが信頼して取り込む物を狙います。だからコードレビューでもログでも気づきにくい。「信頼している=検証していない」が穴になります。
連鎖は「防御の地図」でもある
重要なのは、これが4つのホップの連鎖で、各ホップに止め所があったことです。攻撃手順ではなく、どこで断ち切れたかとして読んでください。
① 信頼するツールを curl | bash で実行(中身を検証せず)
⊘ 止め所:取得物をピン留め+チェックサム検証 / vendoring
② その配布物が“上流で”差し替えられる
自分のコードは無傷なので気づけない。
⊘ 止め所:既知の良いハッシュと照合・固定版を使う
③ CI内の環境変数(秘密・鍵・トークン)が外部へ送信
⊘ 止め所:CI秘密を最小権限・ステップ単位に絞る(全envを渡さない)
④ 盗んだ鍵で本番・他サービスへ二次被害が波及
⊘ 止め所:鍵の定期ローテーション+egress(外向き通信)監視
公表された時系列
2021-01-31
Bash Uploader の改ざんが始まる(以後、断続的に)。2021-03〜
利用企業のCIから秘密情報が外部へ送られ続ける(誰も気づかず)。2021-04-01
ある顧客がチェックサムの食い違いを発見し通報。2021-04-15
Codecov が一般公表。利用企業に秘密の総入れ替えを推奨。2021-04〜
HashiCorp・Twilio・Rapid7 など二次被害が判明。Codecov は後に Bash Uploader を廃止。
根本原因は「1つのミス」ではない
「Codecovが悪い」で終わらせると再発します。利用する側にも層の崩れがありました。
崩れていた構成(事故時)
- CIが取得物を未検証で実行(
curl | bashを信頼任せ) - CI秘密が過剰に露出(全ステップから全環境変数が見える)
- 秘密のローテーションが稀(盗まれた鍵が長く有効)
- CIからの外向き通信を監視していない
守られた構成(再発防止)
- 取得物を固定版+チェックサム検証、または自前に取り込む(vendoring)
- CI秘密は最小権限・必要なステップだけに渡す
- 秘密を定期ローテーション(漏れても寿命を短く)
- CIのegressを監視し、見知らぬ宛先への送信を検知
“信頼”は検証とセットで
サプライチェーン攻撃は、依存ライブラリ・CIツール・ビルドイメージなど「信頼して取り込む物」を狙います。XZ Utils 事件も同じ構図でした。信頼を最小化し、取り込む物の完全性を機械的に検証するのが本命です。
あなたの環境での再発防止
規模を問わず効く、優先順の対策です。「CIが何を信頼して実行しているか」を一度棚卸しすると、自分ごとになります。
取得物の完全性を検証する(curl|bash を信頼任せにしない)
CIで外部スクリプトやバイナリを取り込むなら、固定版(バージョン/コミット固定)+チェックサム(SHA256)照合を必須に。可能なら自前リポジトリに取り込む(vendoring)。今回の検知も、この照合でした。
CIの秘密を最小権限・スコープ化する
全ステップに全環境変数を渡さない。必要なジョブ・ステップにだけ必要な秘密を渡す。短命トークン(OIDC等)を使い、長期キーの常駐を減らす。
秘密を定期ローテーションする
盗まれても寿命が短ければ被害は限定的。定期ローテーションを仕組みにし、供給網インシデントが報じられたら即ローテーション。
CIの外向き通信(egress)を監視する
CIから見知らぬ宛先への送信を検知できるようにする。入口で防ぎ切れなくても、持ち出しの段で気づける層を残す。
ITDの姿勢:信頼を最小化し、検証する
ITD自身も、依存とビルドの取り込みを機械で検証する前提で設計しています。Codecov事件と XZ Utils が示すのは同じこと——「信頼している」は「検証していない」になりがちで、そこが供給網攻撃の入口になる。信頼を減らし、取り込む物の完全性を機械的に確かめることが、当事者にも公開事故にも共通する結論です。
出典(公開記録)
本記事の事実は、以下の公開情報にもとづきます。攻撃の再現手順や改ざんコードは扱わず、防御の教訓に絞っています。
- Codecov 公式「Post-Mortem / Root Cause Analysis (April 2021)」— about.codecov.io
- Codecov 公式「Bash Uploader Security Update」— about.codecov.io
- CISA「Codecov Releases New Detections for Supply Chain Compromise」(2021) — cisa.gov
- Rapid7「Analysis of the Codecov Supply Chain Compromise」(2021) — rapid7.com
次に読む
よくある質問
QCodecov事件の根本原因は何?
自分たちのコードのバグではなく、『CIで信頼して実行していた外部ツール(Codecovの Bash Uploader)が、配布元(上流)で改ざんされた』ことです。CIはそのスクリプトを curl で取ってきて中身を検証せず実行していたため、改ざん版がそのまま動き、CI内の環境変数(秘密情報)が外部へ送られました。
Qなぜ約2か月も気づけなかったの?
改ざんされたのは“他社のツール”で、自分のリポジトリやコードは無傷だったからです。ログにも派手な異常は出ません。最終的に気づけたのは、ある利用企業がスクリプトのチェックサム(SHA256)を公式値と照合し、食い違いを見つけたためでした。
Q小規模な開発でも関係ある?
あります。`curl … | bash` でCIにツールを取り込む構成は個人開発でも一般的で、そこが乗っ取られると一発でCIの秘密が抜かれます。本記事の対策(取得物のピン留め+チェックサム検証・CI秘密の最小権限・定期ローテーション)は規模を問わず有効です。