
n8n 2.42.0 샌드박스 이스케이프에 대한 개념 증명 및 실습 환경: 숨겨진 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 task-runner 자식 프로세스로 옮겼습니다. 프로덕션 스폰 시 --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]에서 열 번의 탐색을 진행했습니다. 표현식 샌드박스, Code/Function/vm2, 자격 증명, 웹훅, 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입니다. Code v2에서 같은 JS: hasProcess: false. Task-runner 자식 프로세스는 pid 26입니다. 증인 N8N-FUNCTION-VM2-WITNESS.
이미 기록된 잘못된 방향들: Function 타입이 숨김/알 수 없음으로 거부됨(그런데 노드는 실제로 제외됨); Function pid가 task-runner 자식 프로세스와 같음(그런데 이미 이동됨); 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를 참조하십시오. 루프백 실습 전용입니다. 보증은 제공되지 않습니다.