CVE-2026-45578
WWBN AVideo Live: OS command injection in on_publish.php execAsync via unescaped m3u8 URL
WWBN AVideo is an open source video platform. In 29.0 and earlier, there is a classic shell-metacharacter injection. The YPTSocket notification branch in plugin/Live/on_publish.php builds an execAsync() command line by string concatenation, single-quoting each argument but never calling escapeshellarg(). A ' in any of the three interpolated values ($users_id, $m3u8, $obj->liveTransmitionHistory_id) closes the quoted token and lets the attacker append arbitrary commands.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.8
WWBN AVideo Live: OS command injection in on_publish.php execAsync via unescaped m3u8 URL
WWBN AVideo is an open source video platform. In 29.0 and earlier, there is a classic shell-metacharacter injection. The YPTSocket notification branch in plugin/Live/on_publish.php builds an execAsync() command line by string concatenation, single-quoting each argument but never calling escapeshellarg(). A ' in any of the three interpolated values ($users_id, $m3u8, $obj->liveTransmitionHistory_id) closes the quoted token and lets the attacker append arbitrary commands.
- Record
CVE-2026-45578- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-02
EUVDEUVD-2026-33310
8.8
WWBN AVideo is an open source video platform. In 29.0 and earlier, there is a classic shell-metacharacter injection. The YPTSocket notification branch in plugin/Live/on_publish.php builds an execAsync() command line by string concatenation, single-quoting each argument but never calling escapeshellarg(). A ' in any of the three interpolated values ($users_id, $m3u8, $obj->liveTransmitionHistory_id) closes the quoted token and lets the attacker append arbitrary commands.
- Record
EUVD-2026-33310- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-xw67-cg5f-4m2r
8.8
AVideo: OS command injection in on_publish.php execAsync via unescaped m3u8 URL
Summary
Type: Classic shell-metacharacter injection. The YPTSocket notification branch in plugin/Live/on_publish.php builds an execAsync() command line by string concatenation, single-quoting each argument but never calling escapeshellarg(). A ' in any of the three interpolated values ($users_id, $m3u8, $obj->liveTransmitionHistory_id) closes the quoted token and lets the attacker append arbitrary commands.
File: plugin/Live/on_publish.php, line 267.
Root cause: the developer wrapped each variable in literal single quotes ('$users_id', '$m3u8', '$obj->liveTransmitionHistory_id') believing this provides shell-quoting. PHP single-quoted-into-shell is not safe quoting; it is just two literal quote characters that the shell pairs greedily. Any embedded ' closes the outer string and resumes interpretation in the shell. The rest of the AVideo codebase already calls escapeshellarg() (137 call sites across the project) for ffmpeg invocations, so the safe primitive is well-known to the project; it was simply omitted from this branch. The endpoint is web-reachable (no .htaccess rule restricts on_publish.php, no REMOTE_ADDR check), so the trigger is a direct HTTP POST without going through nginx-rtmp.
Affected Code
File: plugin/Live/on_publish.php, lines 256-271.
if (AVideoPlugin::isEnabledByName('YPTSocket')) {
$array = setLiveKey($lth->getKey(), $lth->getLive_servers_id());
@ob_clean();
_ob_start();
$lth = new LiveTransmitionHistory($obj->liveTransmitionHistory_id);
$m3u8 = Live::getM3U8File($lth->getKey(), false, true); // value-carrying URL: contains the stream key verbatim
$users_id = $obj->row['users_id'];
$liveTransmitionHistory_id = $obj->liveTransmitionHistory_id;
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
include "{$global['systemRootPath']}plugin/Live/on_publish_socket_notification.php";
} else {
$command = get_php(). " {$global['systemRootPath']}plugin/Live/on_publish_socket_notification.php '$users_id' '$m3u8' '{$obj->liveTransmitionHistory_id}'"; // <-- BUG: literal quotes, no escapeshellarg
$pid = execAsync($command); // sink: shell exec
}
}
Live::getM3U8File($key, false, true) (Live.php:1337-1350 -> Live.php:4845-4889) returns "{$playerServer}{$uuid}.m3u8" (or "{$playerServer}{$uuid}/index.m3u8") where $uuid = $this->getKeyWithIndex(...) is the stream key string read straight out of the live_transmitions table. There is no character normalisation between database read and command construction.
Why it's wrong: '$m3u8' is not shell quoting. PHP interpolates $m3u8 into the string between two literal ' characters. The shell then tokenises the result. If $m3u8 contains ' itself, the shell sees '…' followed by <attacker bytes> followed by another ', which forms two adjacent quoted strings concatenated with whatever the attacker put between them. Embedded ;, backticks, $(), &&, |, or \n then run as shell commands. The fix is escapeshellarg(), which AVideo already uses 137 times in ffmpeg invocations (e.g. getVideos.php:1069, videos.json.php, aVideoEncoder.json.php); this branch simply forgot it.
Exploit Chain
- Attacker authenticates and arranges for one of the command variables to contain
'. Under the current code the readily available primitive is acanStreamuser supplying a stream key via the persistence path (saveLive.php's$_REQUEST['key']is written verbatim tolive_transmitions.key). State: a row exists withkey = "evilkey';id>/tmp/pwn;#". - Attacker POSTs directly to
https://target/plugin/Live/on_publish.php(the file is web-served, no IP restriction) with body:name=evilkey';id>/tmp/pwn;# p=<md5(attacker_password)> tcurl=rtmp://target/live addr=1.2.3.4on_publish.php:117runspreg_replace("/[&=]/", '', $_POST['name'])— only…
- Record
GHSA-xw67-cg5f-4m2r- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-02
NVD
8.8
WWBN AVideo is an open source video platform. In 29.0 and earlier, there is a classic shell-metacharacter injection. The YPTSocket notification branch in plugin/Live/on_publish.php builds an execAsync() command line by string concatenation, single-quoting each argument but never calling escapeshellarg(). A ' in any of the three interpolated values ($users_id, $m3u8, $obj->liveTransmitionHistory_id) closes the quoted token and lets the attacker append arbitrary commands.
- Record
CVE-2026-45578- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-02
OSV
8.8
WWBN AVideo Live: OS command injection in on_publish.php execAsync via unescaped m3u8 URL
WWBN AVideo is an open source video platform. In 29.0 and earlier, there is a classic shell-metacharacter injection. The YPTSocket notification branch in plugin/Live/on_publish.php builds an execAsync() command line by string concatenation, single-quoting each argument but never calling escapeshellarg(). A ' in any of the three interpolated values ($users_id, $m3u8, $obj->liveTransmitionHistory_id) closes the quoted token and lets the attacker append arbitrary commands.
- Record
CVE-2026-45578- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-02
OSVGHSA-xw67-cg5f-4m2r
8.8
AVideo: OS command injection in on_publish.php execAsync via unescaped m3u8 URL
Summary
Type: Classic shell-metacharacter injection. The YPTSocket notification branch in plugin/Live/on_publish.php builds an execAsync() command line by string concatenation, single-quoting each argument but never calling escapeshellarg(). A ' in any of the three interpolated values ($users_id, $m3u8, $obj->liveTransmitionHistory_id) closes the quoted token and lets the attacker append arbitrary commands.
File: plugin/Live/on_publish.php, line 267.
Root cause: the developer wrapped each variable in literal single quotes ('$users_id', '$m3u8', '$obj->liveTransmitionHistory_id') believing this provides shell-quoting. PHP single-quoted-into-shell is not safe quoting; it is just two literal quote characters that the shell pairs greedily. Any embedded ' closes the outer string and resumes interpretation in the shell. The rest of the AVideo codebase already calls escapeshellarg() (137 call sites across the project) for ffmpeg invocations, so the safe primitive is well-known to the project; it was simply omitted from this branch. The endpoint is web-reachable (no .htaccess rule restricts on_publish.php, no REMOTE_ADDR check), so the trigger is a direct HTTP POST without going through nginx-rtmp.
Affected Code
File: plugin/Live/on_publish.php, lines 256-271.
if (AVideoPlugin::isEnabledByName('YPTSocket')) {
$array = setLiveKey($lth->getKey(), $lth->getLive_servers_id());
@ob_clean();
_ob_start();
$lth = new LiveTransmitionHistory($obj->liveTransmitionHistory_id);
$m3u8 = Live::getM3U8File($lth->getKey(), false, true); // value-carrying URL: contains the stream key verbatim
$users_id = $obj->row['users_id'];
$liveTransmitionHistory_id = $obj->liveTransmitionHistory_id;
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
include "{$global['systemRootPath']}plugin/Live/on_publish_socket_notification.php";
} else {
$command = get_php(). " {$global['systemRootPath']}plugin/Live/on_publish_socket_notification.php '$users_id' '$m3u8' '{$obj->liveTransmitionHistory_id}'"; // <-- BUG: literal quotes, no escapeshellarg
$pid = execAsync($command); // sink: shell exec
}
}
Live::getM3U8File($key, false, true) (Live.php:1337-1350 -> Live.php:4845-4889) returns "{$playerServer}{$uuid}.m3u8" (or "{$playerServer}{$uuid}/index.m3u8") where $uuid = $this->getKeyWithIndex(...) is the stream key string read straight out of the live_transmitions table. There is no character normalisation between database read and command construction.
Why it's wrong: '$m3u8' is not shell quoting. PHP interpolates $m3u8 into the string between two literal ' characters. The shell then tokenises the result. If $m3u8 contains ' itself, the shell sees '…' followed by <attacker bytes> followed by another ', which forms two adjacent quoted strings concatenated with whatever the attacker put between them. Embedded ;, backticks, $(), &&, |, or \n then run as shell commands. The fix is escapeshellarg(), which AVideo already uses 137 times in ffmpeg invocations (e.g. getVideos.php:1069, videos.json.php, aVideoEncoder.json.php); this branch simply forgot it.
Exploit Chain
- Attacker authenticates and arranges for one of the command variables to contain
'. Under the current code the readily available primitive is acanStreamuser supplying a stream key via the persistence path (saveLive.php's$_REQUEST['key']is written verbatim tolive_transmitions.key). State: a row exists withkey = "evilkey';id>/tmp/pwn;#". - Attacker POSTs directly to
https://target/plugin/Live/on_publish.php(the file is web-served, no IP restriction) with body:name=evilkey';id>/tmp/pwn;# p=<md5(attacker_password)> tcurl=rtmp://target/live addr=1.2.3.4on_publish.php:117runspreg_replace("/[&=]/", '', $_POST['name'])— only…
- Record
GHSA-xw67-cg5f-4m2r- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
WWBN/AVideoPackagist |
through 29.0 | None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-45578 is a high vulnerability (CVSS 8.8) in Wwbn Avideo, published May 15, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.32%, the 25th percentile. No source names a fixed version.
References
Left out here: the rest of 2 source descriptions. The JSON record has them.