
n8n 2.42.0のサンドボックスエスケープに関するPoCおよびラボ: 隠されたFunction/FunctionItemノードがメインプロセスでJSを実行し、認証済みメンバーにホストRCEを付与する。
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · n8n-function-vm2
解説記事: https://abraxaslabs.tech/research/n8n-function-vm2
n8n 2.42.0 - n8n GmbH
GHSA-j4p8-h8mh-rh8q は n8n-nodes-base.code を JS タスクランナーの子プロセスへ移行した。本番の spawn では --disallow-code-generation-from-strings と --disable-proto=delete が追加される。残されたのは、移行せずに隠したノードである。Function.node.ts は hidden: true である。FunctionItem も同様。LangChain Code も同様。パレットからの非表示は UI フラグにすぎない。ワークフロー JSON の保存/インポートでは依然として型が解決される。デフォルトの NODES_EXCLUDE は Execute Command と Local File Trigger のみである。実行パスは n8n メインプロセス内の vm2 NodeVM 3.12.2 である。
ワークフローを作成できるデフォルトのメンバーは、n8n メインプロセスで JS を実行できる。非表示は ACL ではない。
| ID | CVE 未割当 |
| CWE | CWE-94, CWE-269 |
| CVSS | High: 8.8 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| 製品 | n8n |
| 影響範囲 | 2.42.0 (86c23326) まで; GHSA-j4p8 の残存 |
| 認証 | ワークフローの作成/インポート/実行権限を持つ認証済みメンバー |
| ライセンス | GNU Affero GPL v3.0 |
| ラボ | 127.0.0.1 のみ |
デフォルトのメンバーとして、ノードの type が n8n-nodes-base.function(または functionItem、@n8n/n8n-nodes-langchain.code)であるワークフローをインポートまたは作成し、実行する。その JS は n8n メインプロセス内で実行される。
これは n8n の UID としてのホスト RCE である。インスタンスのシークレット、ディスク上の他ユーザーの認証情報暗号文、DB が対象となる。マルチテナントのメンバーからインスタンスの乗っ取りに至る。OS の LPE ではない。未認証ではない。同一インスタンス上の Code v2 では、そのように process を見ることはできない。
同一製品の類似の残存: Databricks path join。
まず 2026 年 9 月 16 日の GHSA の波を読み、その後タグ [email protected] に対して 10 回の調査を行った。式サンドボックス、Code/Function/vm2、認証情報、Webhook、HTTP/SSRF、Git ノード、コミュニティパッケージ、認証/SSO、ノードインジェクション、パブリック API である。その波の High のほとんどはこのピンでは修正済みである。Code は未完了だった。
v3 の破壊的変更ルールでは、Function / FunctionItem はすでに 削除済み とされている。2.42.0 ではそれらは残存であり、意図された長期的なサンドボックスではない。Function はさらに this.helpers を注入し、そこには JS ランナーが未サポートとしているヘルパーも含まれる。プロセスの境界を証明するのに公開された vm2 ガジェットは必要なかった。
素の n8nio/n8n:2.42.0 を立ち上げ、メンバー(インスタンスオーナーではない)でサインアップし、n8n-nodes-base.function をインポートして実行した。Function の pid=7 は n8n のメイン PID である。同じ JS を Code v2 で実行すると hasProcess: false となる。タスクランナーの子プロセスは pid 26 である。証拠は N8N-FUNCTION-VM2-WITNESS。
すでに記録済みの誤った道筋: Function 型が hidden/unknown として拒否される(実際にはノードが除外されている); Function の pid がタスクランナーの子プロセスと等しい(すでに移行済みである); Code v2 が process を見られる(ランナーが制御点ではない); vm2 のエクスプロイトガジェット、リバースシェル、OS の LPE。いずれも見せかけである。証拠はメイン PID 対 hasProcess: false である。
cd lab
./run.sh
対象は http://127.0.0.1:18201 のみ。デフォルトの NODES_EXCLUDE。攻撃者はメンバーである。
authenticated-as=member
function-fields pid=7 witness=N8N-FUNCTION-VM2-WITNESS
code-fields hasProcess=False pid=None
compare function_pid=7 code_pid=None main_pid=7 runner_pid=26 who=member
SUCCESS N8N-FUNCTION-VM2 who=member function_pid=7 code_pid=None main_pid=7 runner_pid=26 N8N-FUNCTION-VM2-WITNESS
デフォルトの NODES_EXCLUDE に n8n-nodes-base.function、n8n-nodes-base.functionItem、@n8n/n8n-nodes-langchain.code を追加するか、Code v2 がすでに行っているように JsTaskRunnerSandbox 経由でルーティングしてください。パレットの hidden だけでは不十分です。
Function.node.ts · Code.node.ts · nodes.config.ts · task-runner-process-js.tsGNU Affero GPL v3.0。LICENSE を参照してください。ループバックラボ専用です。保証はありません。