Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-33937 — Handlebars.js AST 주입 원격 코드 실행 취약점 | Kitploit
도구/GitHubGitHub/eqstlab/cve-2026-33937
Vulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPapers & ResearchLearning & EducationPayload DevelopmentLabs & Practice
GitHubeqstlab/cve-2026-33937

CVE-2026-33937

Handlebars.js AST 주입 원격 코드 실행 취약점

저장소 보기
213개월 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

이 게시물은 EQSTLab에서 발행한 연구 문서입니다.

참조 PoC: dinhvaren/cve-2026-33937

CVE-2026-33937

★ CVE-2026-33937 Handlebars.js AST 인젝션 원격 코드 실행 PoC ★

https://github.com/user-attachments/assets/99e383e7-e71f-4e10-8c62-f50abff8b4f5


설명

CVE-2026-33937 : Handlebars.js AST 인젝션 원격 코드 실행 취약점

영향을 받는 버전4.0.0 – 4.7.8
패치된 버전4.7.9
CVSS 점수9.8 (Critical)

Handlebars.js의 타입 혼동(Type Confusion) 취약점은 Handlebars.compile()이 템플릿 문자열뿐만 아니라 사전 파싱된 AST 객체(JSON)도 입력으로 허용한다는 사실에서 발생합니다. compile()에 전달되는 값을 제어할 수 있는 공격자는 NumberLiteral 노드의 value 필드가 임의의 JavaScript 문자열로 대체된 조작된 AST 객체를 공급할 수 있습니다. 내부 코드 생성기가 해당 필드를 검증 없이 생성된 JavaScript 함수 본문에 직접 삽입하므로, 결과 함수는 렌더링 시 공격자가 제어하는 코드를 실행하게 되어 서버에서 원격 코드 실행(RCE)을 달성합니다.


실습 환경 구성

Docker를 사용하여 취약한 환경을 빌드하고 실행합니다:

이미지 빌드

root@kitploit:~
docker build -t cve-2026-33937-server .

컨테이너 실행

root@kitploit:~
docker run --name cve-2026-33937 -p 12701:12701 -p 9229:9229 cve-2026-33937-server

또는 제공된 npm 스크립트를 사용할 수 있습니다:

root@kitploit:~
npm run docker:up   # 빌드 및 실행을 한 번에 수행

애플리케이션은 http://localhost:12701에서 서비스됩니다.


사용 방법

웹 UI

브라우저에서 http://localhost:12701을 엽니다. 페이지에는 B2B 이메일 빌더 인터페이스가 표시됩니다. 사용자가 입력한 필드 값은 클라이언트 측에서 Handlebars 템플릿 문자열에 삽입된 후 렌더링을 위해 서버로 전송됩니다. 입력 필드를 통해 또는 API를 직접 통해 악성 Handlebars 페이로드를 주입하십시오.

직접 API 호출

root@kitploit:~
# 조작된 템플릿을 취약한 엔드포인트로 POST 전송
curl -s -X POST http://localhost:12701/api/email/preview \
  -H "Content-Type: application/json" \
  -d '{"subject":"test","editorTemplateData":"<PAYLOAD>"}'

<PAYLOAD>를 Handlebars.compile()을 대상으로 하는 AST 인젝션 페이로드로 교체하십시오.


분석

취약한 엔드포인트

root@kitploit:~
POST /api/email/preview

서버는 editorTemplateData를 포함하는 JSON 본문을 수락하고 이를 검증이나 허용 목록(allowlist) 적용 없이 Handlebars.compile()에 직접 전달합니다:

root@kitploit:~
// app.js
const renderEmail = Handlebars.compile(editorTemplateData);

기술적 근본 원인

Handlebars.compile()은 템플릿 문자열을 입력으로 받는 것으로 문서화되어 있지만, 내부 타입 검사는 사전 파싱된 AST 객체도 직접 전달할 수 있게 허용합니다. javascript-compiler.js 내부에서 NumberLiteral() 방문자(visitor)는 노드의 value 필드를 타입 검증이나 검사 없이 생성된 JavaScript 소스에 그대로 삽입합니다:

root@kitploit:~
// javascript-compiler.js (단순화된 코드)
NumberLiteral(number) {
  this.pushStackLiteral(number.value);   // value가 생성된 JS에 그대로 삽입됨
}

공격자가 number.value가 숫자 리터럴 대신 임의의 JavaScript를 포함하는 문자열(예: "1; require('child_process').execSync(...)")인 조작된 AST 객체를 공급하면, 생성된 함수 본문에 해당 코드가 포함되어 렌더링 시 실행됩니다.

취약한 애플리케이션의 위험한 패턴은 다음과 같습니다:

root@kitploit:~
const render = Handlebars.compile(userInput);  // userInput은 조작된 AST 객체일 수 있음
render(safeContextData);                        // 공격자 코드가 여기서 실행됨

공격 기법 참고 사항: 기존 공개 PoC(참조된 PoC 포함)는 NumberLiteral 노드와 lookup 헬퍼를 결합하여 인젝션을 달성합니다. 이 PoC는 BooleanLiteral 노드와 log 내장 헬퍼를 결합하여 동일한 RCE 프리미티브를 확인함으로써, 타입 혼동이 특정 노드 유형이나 헬퍼 함수에 국한되지 않음을 입증합니다.

공격 흐름

  1. 공격자는 조작된 editorTemplateData 값을 포함하는 POST 요청을 /api/email/preview에 제출합니다.
  2. 서버는 공격자가 제어하는 AST 객체에 대해 Handlebars.compile()을 호출합니다.
  3. 컴파일러는 파싱을 건너뛰고 공격자가 제공한 AST 객체를 직접 처리하여 주입된 리터럴 노드를 코드 생성기에 전달합니다.
  4. 코드 생성은 템플릿 샌드박스를 벗어나는 JavaScript 함수를 생성합니다.
  5. render()를 호출하면 서버 프로세스에서 임의의 JavaScript가 실행됩니다.

이것이 중요한 이유

Handlebars가 Node.js 백엔드 환경에서 구현된 경우, 이 취약점은 일반적인 클라이언트 측 XSS와 달리 서버 측 코드 실행 경로로 이어집니다. 이 공격은 사용자에게 출력이 반영될 필요가 없으며, 페이로드는 애플리케이션과 동일한 권한으로 Node.js 프로세스 내에서 실행됩니다. 배포 방식에 따라:

  • 민감한 파일(예: 애플리케이션 비밀, /etc/passwd)을 읽고 외부로 유출할 수 있습니다.
  • 리버스 셸을 위한 외부 연결을 시작할 수 있습니다.
  • 프로세스에 충분한 파일 시스템 액세스 권한이 있으면 지속성 메커니즘을 설치할 수 있습니다.

시나리오

root@kitploit:~
+-------------------------------------------+
|                  Attacker                 |
+-------------------------------------------+
                      |
                      | POST /api/email/preview
                      | {"editorTemplateData": "<malicious payload>"}
                      v
+-------------------------------------------+
|   Handlebars.compile(editorTemplateData)  |
|   (No sanitization — app.js:17)           |
+-------------------------------------------+
                      |
                      | AST node injection
                      | breaks template sandbox
                      v
+-------------------------------------------+
|  Arbitrary JS Execution (Server Process)  |
+-------------------------------------------+
                      |
                      | Read sensitive files, spawn shell,
                      | exfiltrate secrets, etc.
                      v
+-------------------------------------------+
|        Remote Code Execution (RCE)        |
+-------------------------------------------+

완화 방안

  1. Handlebars.js를 4.7.9 이상으로 업그레이드하십시오.
    버전 4.7.9는 compile()에 엄격한 입력 타입 검증을 도입하여 코드 생성이 시작되기 전에 문자열이 아닌 인수를 거부합니다.

  2. compile()을 호출하기 전에 타입 검사를 강제하십시오.
    즉시 업그레이드가 불가능한 경우, 호출 지점에서 인수가 항상 string인지 검증하십시오:

    root@kitploit:~
    if (typeof templateInput !== 'string') throw new TypeError('Template must be a string');
    const render = Handlebars.compile(templateInput);
    
  3. 빌드 타임 사전 컴파일을 위해 handlebars/runtime을 사용하십시오.
    Handlebars CLI로 빌드 시 템플릿을 사전 컴파일하고 런타임 번들만 배포하십시오. 런타임 빌드에는 compile()이 포함되지 않으므로 프로덕션 배포에서 공격 표면이 완전히 제거됩니다.


면책 조항

이 저장소는 보안 연구, 교육 및 통제된 환경에서의 취약점 시연 목적으로만 제공됩니다. 시스템 소유자의 명시적인 서면 승인 없이 시스템을 테스트하거나 악용하는 데 사용해서는 안 됩니다. 이 프로젝트의 목적은 보안 연구자, 방어자 및 개발자가 취약점을 이해하고, 통제된 실습 환경에서 노출을 검증하며, 효과적인 완화 조치를 적용할 수 있도록 돕는 것입니다.


참고 자료

  • https://handlebarsjs.com/
  • https://github.com/handlebars-lang/handlebars.js
도구 다운로드