2026年2月、広く採用されているオープンソースのワークフロー自動化プラットフォーム「n8n」において、重大なサンドボックス脱出の脆弱性が公表されました。CVE-2026-25049として追跡されているこの脆弱性により、認証済みのユーザーは式評価用サンドボックスを迂回し、ホストサーバー上で任意のシステムコマンドを実行することが可能となり、CVSS v3.1スコア9.9の完全なリモートコード実行を実現します。
OPSWAT ・プログラムの一環として、フェローたちはCVE-2026-25049について、その根本原因、悪用メカニズム、および組織への影響を検証する包括的な技術分析を実施しました。
このブログでは、n8nの式処理アーキテクチャや多層的なセキュリティ制御から、5つの防御層すべてを同時に突破する具体的な手法に至るまで、この脆弱性について詳細に解説します。

CVE-2026-25049 は、n8n に存在する重大な式サンドボックス脱出の脆弱性であり、CWE-913「動的に管理されるコードリソースの不適切な制御」に分類されます。 この脆弱性は、バージョン 1.123.17 以前のすべての n8n バージョンおよびバージョン 2.0.0 から 2.5.1 までに影響を及ぼしますが、バージョン 1.123.17 および 2.5.2 で修正されています。これにより、ワークフロー作成権限を持つ認証済みユーザーが、プラットフォームの式サンドボックスを迂回する悪意のある JavaScript 式を作成し、最終的にホストサーバー上で任意のコマンドを実行することが可能になります。

この脆弱性は、n8nが組織のインフラストラクチャ内で特権的な位置を占めることが多いため、特に深刻です。ワークフロー自動化ハブとして、n8nは通常、内部API、データベース、認証情報ストア、およびサードパーティサービスへの直接的なアクセス権を保持しています。n8nインスタンスが侵害されると、単に自動化サーバーが危険にさらされるだけでなく、接続されたすべてのシステムへの足掛かりとなり、攻撃の影響範囲が劇的に拡大することになります。
CVE-2026-25049は単独で発見された脆弱性ではなく、n8nの式評価器における以前のサンドボックス脱出脆弱性であるCVE-2025-68613に対するパッチの回避手法です。 当初の脆弱性発見後、多層的な防御策が実装されたにもかかわらず、サニタイザーが JavaScript の抽象構文木(AST)ノード型を処理する方法に根本的な欠陥があったため、元の攻撃手法が別の構文ベクトルを通じて再浮上することとなりました。パッチが根本的な設計上の弱点ではなく、特定のエクスプロイト手法に対処するのみであるというこのパターンは、動的コード評価環境のセキュリティ確保における根深い課題を浮き彫りにしています。
この脆弱性は、2026年2月4日にn8nに関する他の10件のセキュリティ勧告とともに公表され、複数のセキュリティ研究チームによって個別に分析されています。
n8nについて
n8nは、組織がシステムを連携させ、プロセスを自動化し、数百ものサービス間で連携を構築できるようにするオープンソースのワークフロー自動化プラットフォームです。広く普及し、1,300以上の連携機能を提供するn8nは、この分野で最も人気のあるツールの一つとなり、開発チームや企業によって、社内ツールからビジネスに不可欠なデータパイプラインに至るまで、あらゆる業務の自動化に活用されています。

このプラットフォームは、セルフホスト型とクラウド型の両方の展開に対応しており、ビジュアルワークフロービルダーに加え、カスタムロジックのための直接的なJavaScriptサポートも提供しています。n8nのアーキテクチャはノードベースであり、ワークフローは相互に接続されたノードで構成され、トリガー、アクション、および関数ステップ間でJSON形式のデータをやり取りします。 実行は、テスト用の手動モードまたは本番環境でのデプロイ用の本番モードで実行できます。このアーキテクチャに加え、JavaScript式へのネイティブサポートや内部APIおよび認証情報ストアへのアクセスが可能であることから、n8nは強力な自動化ツールであると同時に、脆弱性が発生した際には標的となりやすい高価値なターゲットでもあります。
技術的背景
抽象構文木
抽象構文木(AST)とは、パーサーによって生成されるソースコードの階層的な表現である。ASTは、コードを単なる平坦な文字列として扱うのではなく、変数宣言、関数式、メンバ式、識別子、リテラルといった構文要素を表す構造化されたノードに分解する。

n8nのセキュリティ制御はASTレベルで動作するため、この分析においてはASTノードの種類を理解することが不可欠です。サニタイザーは特定のノードの種類を検査し、危険なパターンを検出してブロックします。この脆弱性は、オブジェクトのプロパティへのアクセスという同じ意味論的な操作であっても、使用されるJavaScriptの構文によって全く異なるASTノードの種類が生成されるという事実を悪用しています。

たとえば、式 `obj.constructor` は`MemberExpression` ノードを生成しますが、`const{ constructor } = obj` は 、`Property` ノードを含む `ObjectPattern` を格納した`VariableDeclaration` を生成します 。どちらも同じプロパティを抽出しますが、AST の構造は根本的に異なります。そして、n8n のサニタイザーは前者のパターンのみを検査します。
n8n の式評価とセキュリティアーキテクチャ
n8nのアーキテクチャは、Frontend、CLI、Core、Workflow、Nodesの5つのレイヤーで構成されています。Workflowレイヤーは式の評価を処理しており、これが本脆弱性に関連するコンポーネントです。

n8n では、ワークフローノードのパラメータ内に JavaScript 式を埋め込み、データを動的に操作することができます。これらの式は、Tournament というライブラリを使用してサーバー側で評価されます。Tournament は、実行前に式を AST(抽象構文木)に解析します。サニタイズフックは Tournament の生成プロセスに直接組み込まれており、AST の構築中にチェックを実行することで、コードが実行される前に危険なパターンを検知・阻止します。

これらの式はn8nサーバーと同じNode.jsプロセス内で実行されるため、プラットフォームでは、信頼できないコードがサンドボックスから脱出するのを防ぐために、5つの異なるセキュリティ層が実装されています。
レイヤー1 - グローバルコンテキストの上書き
式が評価される前に、n8nは危険なグローバルオブジェクトや関数を上書きすることで、制限された実行コンテキストを作成します。document、window、globalThis、eval、setTimeout、setInterval、Functionなどのプロパティは空のオブジェクトに置き換えられ、これらの機能への直接アクセスが防止されます。


このアプローチには根本的な限界がある。攻撃者が制限されたコンテキストから抜け出し、実際のグローバルプロセスオブジェクトに到達できてしまう場合、上書きされたプロパティは意味をなさなくなる。
レイヤー2 - 正規表現による検証
式が評価器に到達する前に、n8nは生の式文字列に対して正規表現チェックを行い、コンストラクタプロパティへのアクセスをブロックします。これは、Functionコンストラクタを取得してコードを実行させるための一般的な攻撃経路です。

正規表現/\.\s*constructor/gmは、.constructor へのドット表記によるアクセスを検出します。しかし、JavaScript では同じプロパティにアクセスするための構文が複数存在し、そのすべてがドット表記を用いるわけではないため、このチェックには根本的な限界があります。
レイヤー3 - ASTランタイムサニタイザー – PrototypeSanitizer
最も高度な防御機能は、ASTの構築中に動作します。PrototypeSanitizerフックはASTを走査し、MemberExpressionノードを検査して、アクセスされたプロパティが、constructor、__proto__、prototype、mainModule、bindingなどを含む、安全でないオブジェクトプロパティのブロックリストに含まれているかどうかを判断します。

このサニタイザーは、識別子名をチェックするドット表記(obj.prop)、文字列リテラル値をチェックする静的ブラケット表記(obj['prop'])、およびランタイム・サニタイザー関数でラップされる動的式という、3つのケースに対応しています。図10に示すように、検査の対象となるのはMemberExpressionノードのみであり、デストラクチャリングパターンはトラバースされません。
レイヤー 4 - AST ランタイムサニタイザー関数 ThisSanitizer
CVE-2025-68613 に対する直接的なパッチとして追加された FunctionThisSanitizer は、即時実行関数式(IIFE)をインターセプトし、this を空のオブジェクトにバインドするように書き換えます。これにより、元のエクスプロイトで使用されていた手法、すなわち(function(){ return this })() が、バインドされていない this 参照を通じてグローバルなプロセスオブジェクトを漏洩させるという問題を防止します。

重要な点として、このサニタイザーはFunctionExpressionノードのみを処理します。FunctionExpressionではない呼び出し先(矢印関数を含む)に対しては、明示的に早期に処理を終了します。
eval、Function、process.mainModule などの危険なプロパティは、実行コンテキストから削除または上書きされるため、たとえ上位のレイヤーが迂回されたとしても、コード実行プリミティブへの直接アクセスは阻止されます。
脆弱性分析
根本原因
CVE-2026-25049の根本的な原因は、5つのセキュリティレイヤーすべてに共通する前提条件にあります。各レイヤーは、プロパティへのアクセスがドット表記(obj.constructor)または角括弧表記(obj['constructor'])のいずれかで行われると想定していました。しかし、いずれのレイヤーもJavaScriptのデストラクチャリング構文を考慮していませんでした。
JavaScriptのデストラクチャリングでは、根本的に異なるAST構造を用いてオブジェクトからプロパティを抽出することができます:
// Traditional access - produces MemberExpression node
obj.constructor; // Blocked by regex, AST sanitizer, and runtime checks
// Destructuring - produces ObjectPattern → Property node
const { constructor } = obj; // Not checked by any layer
どちらのパターンも結果は同じですが、生成されるAST表現はまったく異なります。PrototypeSanitizerはMemberExpressionノードのみを検査し、正規表現は.constructorパターンにのみ一致します。解体代入はVariableDeclaration → ObjectPattern → Propertyノードを生成しますが、これらのノードはどのサニタイザーも走査しません。
さらに、n8nにおける矢印関数の処理もこの問題を悪化させています。FunctionThisSanitizerはFunctionExpressionノードのみをインターセプトし、thisを安全なコンテキストにバインドするように書き換えます。一方、矢印関数はArrowFunctionExpression ASTノードを生成しますが、このサニタイザーはこれを処理しません。矢印関数は外側のスコープからthisを継承するため(レキシカルthis)、サニタイズされていないグローバルコンテキストへのアクセスを可能にしてしまいます。
これら2つの見落としが相まって、完全なバイパスが生じます。すなわち、構造化展開によってプロパティへのアクセスチェックを一切トリガーすることなくFunctionコンストラクタが抽出され、さらに矢印関数がFunctionThisSanitizerによってインターセプトされない実行コンテキストを提供するからです。
開発
このエクスプロイトは、これら2つの脆弱性を組み合わせて、すべてのセキュリティ層を同時に突破します。当社の研究チームは、以下の攻撃経路を特定しました:
ステップ 1 - 矢印関数の記述。ペイロードは、即時実行関数式(IIFE)で囲まれた矢印関数から始まります:
={{(() => {
// 矢印関数 - FunctionThisSanitizer をバイパスする
...
})()}}
FunctionThisSanitizer は、呼び出し先が FunctionExpression であるかどうかを確認します。これは ArrowFunctionExpression であるため、サニタイザーは呼び出しを書き換えることなく早期に処理を終了します。この矢印関数は、実際のグローバルコンテキストに完全にアクセスできる状態で実行されます。
ステップ 2 - デストラクチャリングのバイパス。矢印関数内部では、デストラクチャリングによって矢印関数のインスタンスから `Function` コンストラクタが抽出されます:
const { constructor } = () => {};
これは構造分解代入であるため、ASTにはMemberExpressionではなくObjectPatternノードが含まれます。正規表現によるチェックでは.constructorパターンが検出されず、PrototypeSanitizerはプロパティ名を検査することはありません。これにより、攻撃者はFunctionコンストラクタへの参照を保持することになります。
ステップ3 - 動的コード実行。関数コンストラクタを取得した後、攻撃者は任意のコードを作成して実行します:
return constructor(
'return process.mainModule.require("child_process").execSync("whoami").toString()',
)();
動的に構築された関数は、サンドボックス環境の外で実行され、Node.jsのプロセスオブジェクトに完全にアクセスできるため、ホスト上で任意のシステムコマンドを実行することが可能になります。

概念実証
この脆弱性が実際にどのような影響を及ぼすかを実証するため、当社の研究員たちは管理された実験環境下でこのエクスプロイトを再現しました。攻撃シナリオとしては、脆弱性のあるn8nインスタンスをホストし、ノードパラメータ内に悪意のあるペイロードを含むワークフローをインポートするというものです。具体的には、式の評価が可能な「Edit Fields Node」を標的としています。

ワークフローがトリガーされると、ペイロードは5つのサニタイズ層をすべて迂回してホストサーバー上でリバースシェルを実行し、攻撃者に完全なコマンド実行権限を付与する。

Webhookのエスカレーションによる認証不要のRCE
この脆弱性の深刻度は、n8nのWebhook機能と組み合わさると大幅に高まります。n8nでは、ワークフローにおいてHTTPエンドポイントをWebhookとして公開することが可能であり、その際、ベアラートークンやベーシック認証、そして特に重大な点として「認証なし」といった設定可能な認証オプションが用意されています。 ワークフロー作成権限を持つ攻撃者は、認証を「なし」に設定したパブリックWebhookを構成し、接続されたノードにRCEペイロードを埋め込み、ワークフローを起動することができます。その時点で、インターネット上のどこからでもWebhook URLへのHTTPリクエストが送信されると、ホストサーバー上で任意のコマンドが実行されます。
このエスカレーションの経路により、CVE-2026-25049は、認証が必要な内部的な脆弱性から、事実上認証を必要とせず、インターネット全体にさらされる攻撃ベクトルへと変化する。
緩和
n8nチームは、バージョン1.123.17および2.5.2において、サニタイズ関数に適切な実行時型チェックを実装し、デストラクチャリングパターンを処理できるようASTのカバレッジを拡大することで、CVE-2026-25049に対処しました。影響を受けるバージョンを運用している組織は、直ちにアップグレードを行う必要があります。
直ちにアップグレードできない場合は、管理者はワークフローの作成および編集権限を完全に信頼できるユーザーのみに制限し、OSの権限とネットワークアクセスを制限した堅牢な環境でn8nを運用する必要があります。
この脆弱性の深刻度と悪用されやすさ(特に公開Webhookと組み合わされた場合)を考慮すると、組織は既存のワークフローを監査して不審な表現がないか確認し、n8nプロセスから発せられる異常なシステムコマンドの実行を監視するとともに、Webhookの設定を確認して、認証なしで公開されているエンドポイントがないか確認する必要があります。
OPSWATによるリスク軽減
OPSWAT を活用することで、組織は自社のインフラストラクチャ内の脆弱なn8nコンポーネントを迅速に特定し、悪用される前に対策を講じることができます。MetaDefender®プラットフォームの中核技術OPSWAT 、組織の環境全体で使用されているすべてのソフトウェアコンポーネント、ライブラリ、および依存関係の包括的なインベントリを提供します。

図15に示すように、MetaDefender n8nの依存関係を含むpackage.jsonファイルをスキャンし、CVE-2026-25049を自動的に「重大(Critical)」としてフラグ付けするとともに、影響を受けるバージョンの範囲と、修正のための推奨される修正バージョンを表示しました。これにより、セキュリティチームは、自社のデプロイメント環境全体において、この脆弱性を迅速に特定し、優先順位付けを行うことが可能になります。
OPSWAT MetaDefender およびMetaDefender Software Chain™で利用可能であり、セキュリティチームは以下のことが可能になります:
- 脆弱性のあるコンポーネントを迅速に特定 - サンドボックス脱出やコード実行の脆弱性の影響を受けるオープンソースの依存関係を即座に特定し、迅速な修正または削除を可能にします。
- パッチ適用と更新を積極的に実施する- オープンソースコンポーネントを継続的に監視し、古くなったパッケージやセキュリティ上の脆弱性があるパッケージを検知することで、タイムリーな更新を実現し、リスクを低減します。
- コンプライアンスと報告体制の維持- ソフトウェアサプライチェーンにおける透明性が規制枠組みによってますます求められている中、規制要件を満たします。
