Summary
The fix for CVE-2026-33482 (GHSA-pmj8-r2j7-xg6c) is incomplete. That advisory reported that sanitizeFFmpegCommand() (plugin/API/standAlone/functions.php) failed to strip $(...) command substitution, allowing OS command injection at the execAsync() sh -c sink. The fix (commit 25c8ab90) added $, (, ), {, }, \n, \r to the denylist character class and a str_replace('&&', '', ...). It still does not neutralize a single & (the shell background operator), which remains a command separator at the unchanged sink. Same entry point, same sink, same impact as the original — only the surviving metacharacter differs.
Verified at master HEAD.
The surviving gap
HEAD sanitizeFFmpegCommand (functions.php):
$command = str_replace('&&', '', $command); // only the doubled form
$command = preg_replace('/\s*&?>.*(?:2>&1)?/', '', $command); // strips '&' only when followed by '>'
$command = preg_replace('/[;|`<>$()\n\r{}]/', '', $command); // char class has no '&'
// then requires the result to start with 'ffmpeg'
A single & is therefore preserved. ffmpeg ... & <cmd> passes the sanitizer and the strpos(trim($command),'ffmpeg')===0 prefix gate.
Sink (unchanged)
plugin/API/standAlone/ffmpeg.json.php:418 -> execAsync($ffmpegCommand, $keyword). In objects/functionsExec.php::execAsync:
$command = addcslashes($command, '"'); // line 686 — escapes only the double-quote
$commandWithKeyword = "nohup sh -c \"$command & echo \\$! > /tmp/$keyword.pid\" > /dev/null 2>&1 &"; // line 705
exec($commandWithKeyword, ...); // line 712 — PHP exec() runs via /bin/sh -c