Modern Frontend CVEs

対象CVE: CVE-2026-40931

[解説] `compressing`ライブラリにおける危険なファイル上書き脆弱性(CVE-2026-40931)とその対策

`compressing` npmパッケージのv2.1.0以前に存在する脆弱性により、悪意あるアーカイブを解凍するとシステム上の重要ファイルが意図せず上書きされる可能性があります。Node.jsの`path.resolve`の挙動とシンボリックリンクを悪用した攻撃メカニズムを理解し、速やかなアップデートでリスクを回避しましょう。

はじめに:`compressing`ライブラリの危険な脆弱性

フロントエンド開発において、直接アーカイブ(ZIP, TARなど)の解凍処理を記述する機会は少ないかもしれません。しかし、ビルドツール、CI/CDパイプライン、あるいはローカル開発環境で利用されるスクリプトなど、Node.js環境下で動作する様々なツールチェーンが内部的にアーカイブ処理ライブラリを利用しているケースは少なくありません。今回ご紹介するのは、Node.js環境で広く使われているアーカイブ処理ライブラリの一つである`compressing`パッケージ(npmパッケージ名: `compressing`)における深刻な脆弱性です。

この脆弱性(ID: GHSA-4c3q-x735-j3r5 / CVE: CVE-2026-40931)は、深刻度「High」と評価されており、悪用されるとシステム上の任意のファイルが意図せず上書きされる可能性があります。これは、権限昇格やリモートコード実行(RCE)につながる極めて重大なリスクをはらんでいます。Node.js環境を扱う日本のフロントエンドエンジニアの皆さんも、この脆弱性のメカニズムと対策について理解を深めることが重要です。

脆弱性の仕組み:なぜファイルが上書きされるのか?

この脆弱性は、`compressing` npmパッケージのバージョン2.1.0以前におけるアーカイブ解凍時のパス検証が不完全であることに起因します。特に、Node.jsのファイルシステム操作とシンボリックリンクの特性が巧妙に悪用される点がポイントです。

`compressing`ライブラリの以前のバージョンでは、解凍先のパスが、指定された安全なディレクトリ内に収まっているかを文字列ベースでチェックしていました。例えば、`./safe_dir/../etc/passwd`のような「Path Traversal」攻撃を防ぐために、解凍パスが親ディレクトリに遡っていないかを確認するロジックです。しかし、この文字列ベースのチェックだけでは不十分でした。Node.jsの`path.resolve`などのパス操作関数は、あくまで文字列操作であり、実際のディスク上のファイルシステムの状態、特に「シンボリックリンク」の存在を考慮しません。

攻撃者はこの特性を悪用します。攻撃シナリオとしては、まず悪意のあるシンボリックリンク(例えば、`config_file`という名前で`/etc/passwd`や`/etc/shadow`のような重要なシステムファイルを指すリンク)を事前に作成し、それをGitリポジトリに含めます。Gitはシンボリックリンクをそのままクローンするため、被害者がこのリポジトリをクローンすると、悪意のあるシンボリックリンクが被害者のシステムに自動的に配置されます。

その後、アプリケーションが悪意のあるアーカイブ(内部に`config_file`という名前のファイルを含む)を解凍しようとすると、ライブラリは文字列ベースのチェックで「`./safe_dir/config_file`は安全なパスだ」と判断します。しかし、実際にファイルシステムへの書き込みが実行される際、OSカーネルは既存のシンボリックリンクを辿って、意図しない(攻撃者が指定した`/etc/passwd`のような)システムファイルにデータを書き込んでしまいます。

これにより、ライブラリが想定していた安全な論理パスと、OSが実際にデータを書き込む物理パスとの間に乖離が生じ、攻撃者の意図する任意のファイルが上書きされてしまうのです。

フロントエンド開発における影響とリスクシナリオ

直接的なフロントエンドアプリケーションが`compressing`ライブラリを解凍処理に用いることは稀かもしれませんが、Node.jsを基盤とする開発エコシステム全体で考慮すべきリスクが存在します。

1. **ビルドプロセスやCI/CDパイプライン:** CI/CD環境で、外部から取得したアセットバンドルやテーマファイルなどがアーカイブ形式で提供され、それをビルドスクリプトやカスタムタスクランナー(Gulp/Gruntのカスタムプラグインなど)で解凍している場合。悪意のあるアーカイブが混入すると、ビルドサーバーの重要な設定ファイルが上書きされる可能性があります。

2. **ローカル開発環境での利用:** 例えば、CMSのテーマ開発などで、Gitリポジトリからクローンしたプロジェクト内に悪意のあるシンボリックリンクが仕込まれており、その後、そのプロジェクトが特定のアーカイブを解凍するスクリプトを実行すると、開発者のシステムファイルが危険に晒される可能性があります。

3. **Node.jsベースのバックエンドサービス:** フロントエンドエンジニアが関わることも多いBFF (Backend For Frontend) や、Node.jsで書かれた静的サイトジェネレーターのサーバーサイド処理などで、ユーザーがアップロードしたアーカイブファイルを解凍する機能がある場合、この脆弱性の直接的な影響を受けます。

特に、解凍処理が`root`や管理者権限で実行される環境では、システムファイルの上書きによる権限昇格やリモートコード実行に直結する可能性があり、その影響は甚大です。

今すぐできる対策

この脆弱性からシステムを保護するために、以下の対策を速やかに実施してください。

最も重要かつ直接的な対策は、`compressing`ライブラリを、この脆弱性が修正された最新バージョンに速やかにアップデートすることです。脆弱性はバージョン2.1.0以前に存在するため、それ以降のバージョン(特に最新安定版)への更新が推奨されます。プロジェクトの`package.json`を確認し、以下のコマンドでアップデートを行ってください。

```bash npm install compressing@latest # または yarn add compressing@latest ```

依存関係ツリーの奥深くで`compressing`が使われている場合、`npm audit fix`や`yarn audit --fix`も有効な場合がありますが、`package-lock.json`や`yarn.lock`を直接確認し、確実にバージョンが上がっていることを確認してください。

アップデートがすぐにできない場合や、セキュリティの多層防御として、解凍するアーカイブやそれをホストするGitリポジトリが信頼できるソースからのものであることを厳しく確認してください。不審なソースからのファイルは絶対に解凍しない、開発環境にクローンしないという基本原則を徹底しましょう。

これは`compressing`ライブラリの開発者が行うべき根本的な修正ですが、もし自作の解凍ライブラリや同様のパス操作を行うユーティリティを開発している場合は、参考にすべき重要な原則です。今後のライブラリ開発においては、パスの検証を単なる文字列比較だけでなく、Node.jsの`fs.lstatSync()`(または非同期版の`fs.promises.lstat`)のようなファイルシステムAPIを使用して、パスの各セグメントがシンボリックリンクではないかを再帰的にチェックする「状態認識型」の検証を実装する必要があります。これにより、論理パスと物理パスの乖離を防ぎ、シンボリックリンクを利用した攻撃を完全に阻止できます。

まとめ

この`compressing`の脆弱性は、一見すると地味に見える「パス検証」がいかに複雑で重要であるか、そしてNode.jsのファイルシステムAPIの特性を深く理解することの重要性を再認識させるものです。フロントエンドエンジニアの皆さんも、自身が利用するツールやライブラリのセキュリティに常に意識を向け、定期的なアップデートと情報収集を心がけることで、予期せぬリスクから自身の開発環境やプロジェクトを守ることができます。

← ブログ一覧に戻る