해당 취약점은 Markdown 파일을 HTML로 렌더링한 뒤, headless Chrome을 사용해 PDF로 변환하는 Node.js 기반 도구인 md-to-pdf에서 발생했습니다. CVE-2025-65108은 md-to-pdf가 Markdown 파일의 front-matter(YAML 메타데이터 블록)를 처리하는 과정에서 발생한 코드 실행 취약점입니다.
---
title: 타이틀
slug: main
---
Markdown 파일의 front-matter는 보통 --- 로 둘러싸인 YAML 메타데이터 블록으로, md-to-pdf는 이를 gray-matter 라이브러리를 사용해 파싱하게 됩니다. 문제는 gray-matter가 기본 yaml 구분자 외에도 —-json, —-javascript와 같은 delimiter도 지원한다는 점이며, 이러한 delimiter가 사용되면 front-matter 내용을 해당 언어(JavaScript 등)로 평가하게 됩니다.
md-to-pdf는 파싱된 front-matter를 추가 검증 없이 템플릿 엔진에 그대로 전달했기 때문에, 공격자가 조작된 Markdown 파일만 업로드해도 변환 과정에서 JavaScript 코드가 실행되어 RCE로 이어질 수 있습니다.
// [1]
const { mdToPdf } = require('md-to-pdf');
// [2]
var payload = '---javascript\n((require("child_process")).execSync("calc.exe"))\n---RCE';
// [3]
(async () => {
await mdToPdf({ content: payload }, { dest: './output.pdf'});
})();
[1] Markdown 문자열을 HTML → PDF로 변환하는 md-to-pdf 모듈을 불러오는 코드입니다.
이 때, [2] payload 변수에는 JavaScript front-matter (—-javascript)가 포함된 내용을 작성할 수 있고, gray-matter가 이 구분자를 만나면, front-matter 내부의 내용을 javascript 코드로 평가하게 됩니다. (ex. Node.js의 child_process 모듈 호출)
만약 [3] async 함수 내에서 mdToPdf()를 호출하면 변환 과정에서 front-matter가 파싱되며, 결과적으로 Markdown → PDF 변환을 수행하는 Node.js 프로세스의 권한으로 임의 코드가 실행될 수 있습니다.