Modern Frontend CVEs

対象CVE: GHSA-5p4m-2wfm-xmqj

[技術解説] js-yamlにおけるサービス拒否(DoS)の脆弱性 (GHSA-5p4m-2wfm-xmqj)

js-yamlライブラリのバージョン3.xおよび4.x系に、特定のYAML構造(`!!omap`)のパース時に二次曲線的にCPUを消費する脆弱性(GHSA-5p4m-2wfm-xmqj)が発見されました。この問題は、悪意のあるYAML入力によってNode.jsのイベントループをブロックし、サービス拒否(DoS)を引き起こす可能性があります。

はじめに:なぜフロントエンドエンジニアがjs-yamlの脆弱性を気にするべきか

フロントエンド開発において、直接YAMLファイルを扱う機会はバックエンドに比べて少ないかもしれません。しかし、WebpackやViteなどのビルドツールの設定、RenovateやDependabotといった依存関係管理ツールの設定ファイル、あるいはCI/CDパイプラインの定義などでYAMLが間接的に利用されることは珍しくありません。

また、Node.jsベースのツールチェーンや、サーバーサイドレンダリング(SSR)、APIゲートウェイなどのNode.jsアプリケーションを開発している場合、依存パッケージの脆弱性は直接的な脅威となります。外部からの信頼できない入力を処理する可能性があれば、その安全性確保は非常に重要です。今回の脆弱性も、そのような文脈であなたのアプリケーションに影響を与える可能性があります。

脆弱性の概要:`!!omap`による二次曲線的なCPU消費

今回の脆弱性 (GHSA-5p4m-2wfm-xmqj) は、広く使われているYAMLパーサーライブラリ`js-yaml`のバージョン3.xおよび4.x系に存在します。問題は、YAMLの特定のデータ型である`!!omap` (Ordered Map) を解決する際の処理効率にあります。

`!!omap`は、キーの重複が許されない「順序付きマップ」を表現するものです。js-yamlの当該バージョンでは、このキーの重複チェックを`Array.prototype.indexOf()`を使って実装しています。

技術的な詳細:O(n²)のパフォーマンス問題

`Array.prototype.indexOf()`は配列全体を線形探索するため、各要素を追加するたびに配列の長さに比例した時間がかかります。`!!omap`の要素が`n`個ある場合、全体の処理時間は約`1 + 2 + ... + n`となり、結果的に**O(n²)**の二次曲線的な計算量となります。これは、要素数が増えるほど処理時間が爆発的に増大することを意味します。

悪意のある攻撃者は、この特性を悪用し、巨大な`!!omap`構造を持つYAMLドキュメントを作成し、これを`js-yaml`にパースさせることで、サーバー(Node.jsプロセス)のCPUを長時間占有させることが可能になります。

このCPUを大量消費する処理は`yaml.load()`内で同期的に実行されるため、Node.jsのイベントループが完全にブロックされます。これにより、そのプロセスで処理されている他のすべてのリクエストも停止し、最終的に**サービス拒否(DoS)**状態に陥ります。`!!omap`は`js-yaml`の**デフォルトスキーマ**に登録されているため、特別な設定なしに`yaml.load(untrustedInput)`を使用している場合、この脆弱性の影響を受けます。

影響を受けるバージョンとCVE-2026-59870との関連

この脆弱性の影響を受けるのは、`js-yaml`の**3.x系(3.15.0まで)**および**4.x系(4.3.0まで)**です。

興味深いことに、この問題は`js-yaml`の5.x系で既に修正されています(CVE-2026-59870 / GHSA-724g-mxrg-4qvm として報告され、バージョン5.2.1で修正済み)。5.x系では、重複キーのチェックに効率的な`Set`データ構造を使用することで、処理を**O(n)**に改善しています。しかし、この修正が3.x/4.x系にはバックポートされていないため、現在でもこれらの旧バージョンには脆弱性が残っています。

提供されたProof of Concept(概念実証)では、要素数が2倍になるごとにパース時間が約4倍になることが示されており、O(n²)の特性が明確に表れています。例えば、15万エントリの約2.5MBのYAMLドキュメントのパースに10秒以上かかることが実測されており、わずかな入力でシステムを長時間停止させることが可能です。

対策:速やかなアップデートを推奨

最も効果的かつ推奨される対策は、`js-yaml`を脆弱性のないバージョン、すなわち**5.2.1以降の5.x系へアップデート**することです。これにより、効率的な`Set`ベースの重複チェックが利用され、O(n)の線形時間でパース処理が行われるようになります。

プロジェクトの依存関係や既存コードとの互換性により、すぐに5.x系へアップグレードできない場合もあるかもしれません。その場合、信頼できないソースからのYAML入力をパースしない、あるいは入力サイズや構造に厳密な制限を設けるといった緩和策も検討できますが、これらは根本的な解決にはなりません。可能な限り、安全なバージョンへのアップデートを目指してください。

あなたのプロジェクトの`package.json`や`package-lock.json`を確認し、`js-yaml`のバージョンが脆弱性のある範囲(3.x系、4.x系)に含まれていないか確認しましょう。もし含まれている場合は、速やかにアップデート計画を立てることを強く推奨します。

まとめ

`js-yaml`の`!!omap`パースにおけるO(n²)の脆弱性は、Node.jsアプリケーションのイベントループをブロックし、サービス拒否につながる深刻な問題です。フロントエンドエンジニアも、自身の開発環境やアプリケーションが依存するパッケージのセキュリティに注意を払い、常に最新のセキュリティ情報にアンテナを張ることが求められます。

本脆弱性の影響からプロジェクトを守るため、今一度依存関係を確認し、安全なバージョンへの更新を強く推奨します。

← ブログ一覧に戻る