
Advisory e prova de conceito para injeção de comandos do sistema operacional em um auxiliar MCP ffmpeg, com análise de causa raiz, orientação para detecção e mitigações para um pacote npm não corrigido.
runFFmpegCommand passa uma string construída a partir dos parâmetros da ferramenta MCP para
spawn(…, { shell: true }), de modo que metacaracteres de shell em options, format,
codec, pixelFormat ou extraOptions são executados no host que executa o servidor.
⚠ Não existe versão corrigida
Em 2026-08-22, o lançamento mais recente do npm é o 0.2.1, que é a versão afetada, e o sink ainda está presente no branch padrão do repositório. Não há para o que atualizar. Consulte Mitigação para saber o que os usuários podem fazer nesse meio-tempo.
Os argumentos de ferramentas MCP sofrem influência do atacante. Eles são produzidos por um LLM a partir
do conteúdo que o agente processa — documentos, páginas da web, saída de ferramentas — portanto,
injeção indireta de prompt coloca o atacante no controle dos valores que um manipulador
de ferramentas recebe. Um manipulador que alimenta qualquer um desses valores em um shell transforma
essa influência em execução de código no host que executa o servidor MCP. Este é
o mesmo modelo do caso precedente aws-mcp-server / CVE-2026-5058.
Um servidor de conversão de mídia é um alvo particularmente natural para isso: os arquivos que ele é solicitado a processar são exatamente o conteúdo não confiável que um agente coleta de outros lugares.
src/utils/ffmpeg.ts — o comando é montado como uma string e o shell é
habilitado explicitamente:
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 }) executa a string inteira por meio de
/bin/sh -c. Tudo o que o chamador contribuiu para command é sintaxe de shell.
src/tools/handlers.ts alcança esse auxiliar a partir de três ferramentas, interpolando
parâmetros que nunca são validados quanto ao conteúdo:
| Ferramenta | Parâmetros injetáveis |
|---|---|
convert_video |
Apenas inputPath e outputPath são verificados de alguma forma, e os esquemas Zod
validam o tipo (z.string()), nunca o conteúdo — portanto, metacaracteres passam
direto.
Uma chamada convert_video com options definido como ; touch /tmp/marker ; produz:
/bin/sh -c "ffmpeg -i /tmp/in.mp4 ; touch /tmp/marker ; /tmp/out.mp4"
poc/driver.mjs fala MCP via stdio: ele inicializa o
servidor, emite uma chamada tools/call para convert_video com um valor options
injetado e verifica a existência de um arquivo marcador. O payload é um touch inofensivo.
npm pack @sworddut/[email protected]
tar xf sworddut-mcp-ffmpeg-helper-0.2.1.tgz && cd package && npm install
node ../poc/driver.mjs
Esperado em uma versão afetada:
==== POC RESULT (@sworddut/mcp-ffmpeg-helper) ====
marker /tmp/PWNED_ffmpeg created: true
verdict: CONFIRMED — command injection executed
ffmpeg não precisa estar instalado — o comando injetado é executado na mesma
string /bin/sh -c, independentemente de o binário inicial ser resolvido.
Validado em 2026-06-01 em um contêiner isolado, revalidado em 2026-06-13, e o
sink novamente confirmado no branch padrão em 2026-08-22. Execute-o apenas
contra infraestrutura que você está autorizado a testar.
ffmpeg contendo ;, &&, ||, |, uma crase ou $(.
Invocações legítimas de ffmpeg deste servidor não contêm.sh -c cuja linha de comando começa com ffmpeg e contém um
segundo comando após um separador — um sinal na árvore de processos (auditd, eBPF,
Falco, EDR) que não depende do registro de aplicação.ffmpeg e ffprobe são
esperados; um shell, um interpretador ou um cliente de rede não são.Running FFmpeg command: ffmpeg <command>, que é o lugar mais barato para
identificar um valor injetado se os logs forem coletados.options, format, , ou
contenham metacaracteres de shell.MITRE ATT&CK T1059.004 Command and Scripting Interpreter: Unix Shell.
Não existe lançamento corrigido, portanto as opções são contenção e remoção:
runFFmpegCommand.A correção upstream é remover shell: true e passar ao ffmpeg um vetor de
argumentos — spawn("ffmpeg", ["-i", inputPath, …]) — construindo esse array a partir
de valores format, codec e pixelFormat permitidos (allowlist), em vez de
strings de forma livre. Validação de conteúdo, não apenas validação de tipo Zod, é o
requisito subjacente.
NIST SP 800-53r5 SI-10; OWASP ASVS v4 §5.3.8; mitigações CWE-78 M1 e M2.
aws-mcp-server)Avisos complementares da mesma rodada de pesquisa: CVE-2026-52616, CVE-2026-52618.
MIT — consulte LICENSE.
| CVE | CVE-2026-52617 |
| CWE | CWE-78 (Improper Neutralization of Special Elements used in an OS Command) |
| Pacote | @sworddut/mcp-ffmpeg-helper (npm) |
| Afetado | 0.2.1 e anteriores — todas as versões publicadas |
| Corrigido em | nenhuma |
| CVSS v3.1 | AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 7.8 Alto (transporte stdio). AV:N → 9.8 Crítico se o servidor estiver envolvido em um transporte de rede. |
| Relatado por | s1ko (github.com/s1ko, [email protected]) |
| CVE atribuído | 2026-07-13, MITRE CNA-LR |
options |
extract_audio | format |
create_video_from_images | codec, pixelFormat, extraOptions |
codecpixelFormatextraOptions| Data | Evento |
|---|
| 2026-05-29 | Vulnerabilidade identificada por revisão de código-fonte do tarball publicado |
| 2026-06-01 | Validada dinamicamente via MCP stdio em um contêiner isolado |
| 2026-06-13 | Revalidada em um segundo host; o repositório não possui Private Vulnerability Reporting habilitado, e os campos package.json repository/bugs/homepage permanecem no modelo github.com/yourusername, sem deixar um contato de segurança documentado |
| 2026-07-13 | MITRE CNA-LR atribui CVE-2026-52617, com s1ko creditado como descobridor |
| 2026-08-22 | Sink reconfirmado no branch padrão; o npm mais recente ainda é 0.2.1; este relatório publicado |