
수정되지 않은 npm 패키지의 MCP ffmpeg 헬퍼에서 발생하는 OS 명령어 주입에 대한 보안 권고 및 개념 증명(PoC)으로, 근본 원인 분석, 탐지 가이드, 완화 조치를 포함합니다.
runFFmpegCommand는 MCP 도구 매개변수로 구성된 문자열을
spawn(…, { shell: true })에 전달하므로, options, format,
codec, pixelFormat 또는 extraOptions에 포함된 셸 메타문자가 서버를 실행하는 호스트에서 실행됩니다.
⚠ 수정된 버전이 존재하지 않습니다
2026-08-22 기준 최신 npm 릴리스는 0.2.1이며, 이는 영향을 받는 버전이고 해당 싱크는 여전히 저장소의 기본 브랜치에 존재합니다. 업그레이드할 대상이 없습니다. 그동안 사용자가 할 수 있는 조치에 대해서는 완화를 참조하십시오.
| CVE | CVE-2026-52617 |
| CWE | CWE-78 (OS 명령에 사용되는 특수 요소의 부적절한 중화) |
| 패키지 | @sworddut/mcp-ffmpeg-helper (npm) |
| 영향 받는 버전 | 0.2.1 및 이전 — 게시된 모든 버전 |
| 수정된 버전 | 없음 |
| CVSS v3.1 | AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 8.4 High (stdio 전송). 네트워크 전송으로 서버를 감싸는 경우 AV:N → 9.8 Critical. |
| 보고자 | s1ko (github.com/s1ko, [email protected]) |
| CVE 할당 | 2026-07-13, MITRE CNA-LR |
MCP 도구 인수는 공격자의 영향을 받습니다. 이는 에이전트가 처리하는
콘텐츠 — 문서, 웹 페이지, 도구 출력 — 로부터 LLM이 생성하므로,
간접 프롬프트 주입을 통해 공격자가 도구 핸들러가 받는 값을 제어할 수 있습니다.
이러한 값 중 하나라도 셸로 전달하는 핸들러는 그 영향력을
MCP 서버를 실행하는 호스트에서의 코드 실행으로 바꿉니다. 이는 선례 사례인
aws-mcp-server / CVE-2026-5058과 동일한 모델입니다.
미디어 변환 서버는 특히 이 공격의 자연스러운 표적입니다. 처리하도록 요청받는 파일이 바로 에이전트가 다른 곳에서 가져오는 신뢰할 수 없는 콘텐츠이기 때문입니다.
src/utils/ffmpeg.ts — 명령은 문자열로 조립되며 셸이
명시적으로 활성화됩니다:
function runProcess(command: string, args: string[], useShell = false) {
const child = spawn(command, args, { shell: useShell, windowsHide: true });
…
}
export async function runFFmpegCommand(command: string): Promise<string> {
const { stdout, stderr, code } = await runProcess(`ffmpeg ${command}`, [], true);
…
}
spawn("ffmpeg " + command, [], { shell: true })는 전체 문자열을
/bin/sh -c를 통해 실행합니다. 호출자가 command에 기여한 모든 것이 셸 구문이 됩니다.
src/tools/handlers.ts는 세 개의 도구에서 해당 헬퍼에 도달하며, 내용에 대해
전혀 검증되지 않는 매개변수를 보간합니다:
| 도구 | 주입 가능한 매개변수 |
|---|---|
convert_video | options |
extract_audio | format |
create_video_from_images | codec, pixelFormat, extraOptions |
inputPath와 outputPath만 전혀 검사되며, Zod 스키마는 타입(z.string())만
검증하고 내용은 결코 검증하지 않으므로 메타문자가 그대로 통과합니다.
options가 ; touch /tmp/marker ;로 설정된 convert_video 호출은 다음을 생성합니다:
/bin/sh -c "ffmpeg -i /tmp/in.mp4 ; touch /tmp/marker ; /tmp/out.mp4"
poc/driver.mjs는 stdio를 통해 MCP와 통신합니다. 서버를 초기화하고, 주입된 options 값과 함께 convert_video에 대한 tools/call을 한 번 발행한 뒤, 마커 파일을 확인합니다. 페이로드는 무해한 touch입니다.
npm pack @sworddut/[email protected]
tar xf sworddut-mcp-ffmpeg-helper-0.2.1.tgz && cd package && npm install
node ../poc/driver.mjs
영향받는 버전에서 예상되는 결과:
==== POC RESULT (@sworddut/mcp-ffmpeg-helper) ====
marker /tmp/PWNED_ffmpeg created: true
verdict: CONFIRMED — command injection executed
ffmpeg는 설치할 필요가 없습니다. 앞의 바이너리가 해석되는지 여부와 관계없이 주입된 명령은 동일한 /bin/sh -c 문자열에서 실행됩니다.
2026-06-01에 격리된 컨테이너에서 검증되었고, 2026-06-13에 재검증되었으며,
2026-08-22에 기본 브랜치에서 싱크가 여전히 존재함을 재확인했습니다. 테스트 권한이 있는
인프라에 대해서만 실행하십시오.
;, &&, ||, |, 백틱 또는 $(를 포함하는 ffmpeg 명령줄.
이 서버에서의 정당한 ffmpeg 호출에는 이러한 문자가 포함되지 않습니다.ffmpeg로 시작하고 구분자 뒤에 두 번째 명령이 포함된 sh -c 프로세스
— 애플리케이션 로깅에 의존하지 않는 프로세스 트리 신호(auditd, eBPF, Falco, EDR).ffmpeg와 ffprobe는 예상되지만,
셸, 인터프리터 또는 네트워크 클라이언트는 예상되지 않습니다.Running FFmpeg command: ffmpeg <command>로 기록하며, 로그가 수집된다면 주입된 값을
발견할 수 있는 가장 저렴한 지점입니다.options, format, codec, pixelFormat 또는
extraOptions에 셸 메타문자가 포함된 MCP 도구 호출 로그.MITRE ATT&CK T1059.004 Command and Scripting Interpreter: Unix Shell.
패치된 릴리스가 존재하지 않으므로, 선택지는 격리와 제거입니다:
runFFmpegCommand에 도달하기 전에 셸 메타문자를
거부하도록 서버를 래핑하거나 포크하십시오.업스트림 수정은 shell: true를 제거하고 ffmpeg에 인수 벡터를 전달하는 것입니다
— spawn("ffmpeg", ["-i", inputPath, …]) — 이 배열을 자유 형식 문자열이 아닌
허용 목록에 포함된 format, codec, pixelFormat 값으로 구성하는 것입니다.
Zod 타입 검증만이 아닌 콘텐츠 검증이 근본적인 요구사항입니다.
NIST SP 800-53r5 SI-10; OWASP ASVS v4 §5.3.8; CWE-78 완화책 M1 및 M2.
| 날짜 | 사건 |
|---|---|
| 2026-05-29 | 게시된 tarball의 소스 검토를 통해 취약점 식별 |
| 2026-06-01 | 격리된 컨테이너에서 MCP stdio를 통해 동적으로 검증 |
| 2026-06-13 | 두 번째 호스트에서 재검증; 저장소에 Private Vulnerability Reporting이 활성화되어 있지 않고, package.json의 repository/bugs/homepage 필드가 github.com/yourusername 템플릿으로 남아 있어 문서화된 보안 연락처가 없음 |
| 2026-07-13 | MITRE CNA-LR이 CVE-2026-52617 할당, s1ko를 발견자로 기재 |
| 2026-08-22 | 기본 브랜치에서 싱크 재확인; npm 최신 버전은 여전히 0.2.1; 본 분석 문서 게시 |
aws-mcp-server)동일한 연구 과정에서 나온 동반 권고문: CVE-2026-52616, CVE-2026-52618.
MIT — LICENSE 참조.