
Aviso y prueba de concepto de inyección de comandos del sistema operativo en un asistente ffmpeg de MCP, con análisis de causa raíz, orientación para detectores y mitigaciones para un paquete npm sin corregir.
runFFmpegCommand pasa una cadena construida a partir de parámetros de la herramienta MCP a
spawn(…, { shell: true }), por lo que los metacaracteres del shell en options, format,
codec, pixelFormat o extraOptions se ejecutan en el host que ejecuta el servidor.
⚠ No existe una versión corregida
A fecha de 2026-08-22, la última versión publicada en npm es la 0.2.1, que es la versión afectada, y el punto de ejecución vulnerable sigue presente en la rama por defecto del repositorio. No hay nada a lo que actualizar. Consulte Mitigación para saber qué pueden hacer los usuarios mientras tanto.
| CVE | CVE-2026-52617 |
| CWE | CWE-78 (Neutralización incorrecta de elementos especiales utilizados en un comando del sistema operativo) |
| Paquete | @sworddut/mcp-ffmpeg-helper (npm) |
| Afectados | 0.2.1 y anteriores — todas las versiones publicadas |
| Corregido en | ninguna |
| CVSS v3.1 | AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 8.4 Alta (transporte stdio). AV:N → 9.8 Crítica si el servidor se envuelve en un transporte de red. |
| Reportado por | s1ko (github.com/s1ko, [email protected]) |
| CVE asignado | 2026-07-13, MITRE CNA-LR |
Los argumentos de las herramientas MCP están influenciados por el atacante. Los produce un LLM a partir
del contenido que procesa el agente —documentos, páginas web, salida de herramientas—, por lo que la
inyección indirecta de prompts pone a un atacante en control de los valores que recibe un manejador de
herramientas. Un manejador que introduce cualquiera de esos valores en un shell convierte esa influencia
en ejecución de código en el host que ejecuta el servidor MCP. Este es el mismo modelo que el caso
precedente aws-mcp-server / CVE-2026-5058.
Un servidor de conversión de medios es un objetivo especialmente natural para esto: los archivos que se le pide procesar son exactamente el contenido no confiable que un agente recoge de otros lugares.
src/utils/ffmpeg.ts — el comando se ensambla como una cadena y el shell se
habilita explícitamente:
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 }) ejecuta toda la cadena a través de
/bin/sh -c. Todo lo que el llamador aportó a command es sintaxis del shell.
src/tools/handlers.ts llega a ese helper desde tres herramientas, interpolando
parámetros que nunca se validan en cuanto a contenido:
| Herramienta | Parámetros inyectables |
|---|---|
convert_video | options |
extract_audio | format |
create_video_from_images | codec, pixelFormat, extraOptions |
Solo inputPath y outputPath se comprueban en absoluto, y los esquemas de Zod
validan el tipo (z.string()), nunca el contenido — por lo que los metacaracteres pasan
directamente.
Una llamada a convert_video con options establecido en ; touch /tmp/marker ; produce:
/bin/sh -c "ffmpeg -i /tmp/in.mp4 ; touch /tmp/marker ; /tmp/out.mp4"
poc/driver.mjs habla MCP sobre stdio: inicializa el
servidor, emite un tools/call para convert_video con un valor options
inyectado, y comprueba la existencia de un archivo marcador. La carga útil es un 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 en una versión afectada:
==== POC RESULT (@sworddut/mcp-ffmpeg-helper) ====
marker /tmp/PWNED_ffmpeg created: true
verdict: CONFIRMED — command injection executed
ffmpeg no necesita estar instalado — el comando inyectado se ejecuta en la misma cadena /bin/sh -c independientemente de si el binario inicial se resuelve o no.
Validado el 2026-06-01 en un contenedor aislado, revalidado el 2026-06-13, y el
sumidero reconfirmado presente en la rama por defecto el 2026-08-22. Ejecútalo solo
contra infraestructura que estés autorizado a probar.
ffmpeg que contenga ;, &&, ||, |, un backtick o $(.
Las invocaciones legítimas de ffmpeg desde este servidor no lo hacen.sh -c cuya línea de comandos empiece por ffmpeg y contenga un
segundo comando tras un separador — una señal de árbol de procesos (auditd, eBPF,
Falco, EDR) que no depende del registro de la aplicación.ffmpeg y
ffprobe; un shell, un intérprete o un cliente de red no lo son.Running FFmpeg command: ffmpeg <command>, que es el lugar más barato para
detectar un valor inyectado si los registros se recopilan.options, format, codec, pixelFormat o
extraOptions contengan metacaracteres de shell.MITRE ATT&CK T1059.004 Command and Scripting Interpreter: Unix Shell.
No existe una versión parcheada, así que las opciones son la contención y la eliminación:
runFFmpegCommand.La corrección upstream es eliminar shell: true y pasar a ffmpeg un vector
de argumentos — spawn("ffmpeg", ["-i", inputPath, …]) — construyendo ese array a partir de
valores de format, codec y pixelFormat en lista blanca en lugar de cadenas de
forma libre. La validación de contenido, no solo la validación de tipos de Zod, es el
requisito subyacente.
NIST SP 800-53r5 SI-10; OWASP ASVS v4 §5.3.8; mitigaciones M1 y M2 de CWE-78.
| Fecha | Evento |
|---|---|
| 2026-05-29 | Vulnerabilidad identificada mediante revisión del código fuente del tarball publicado |
| 2026-06-01 | Validada dinámicamente sobre MCP stdio en un contenedor aislado |
| 2026-06-13 | Revalidada en un segundo host; el repositorio no tiene habilitado Private Vulnerability Reporting, y los campos repository/bugs/homepage de package.json se dejan en la plantilla github.com/yourusername, sin dejar ningún contacto de seguridad documentado |
| 2026-07-13 | MITRE CNA-LR asigna CVE-2026-52617, s1ko acreditado como descubridor |
| 2026-08-22 | Sumidero reconfirmado en la rama por defecto; npm latest sigue en 0.2.1; este informe publicado |
aws-mcp-server)Avisos complementarios de la misma pasada de investigación: CVE-2026-52616, CVE-2026-52618.