GHSA-8wf4-c4x3-h952 AVideo: Remote Code Execution via PHP Temp File in Encoder downloadURL
SummaryThe `downloadVideoFromDownloadURL()` function in `objects/aVideoEncoder.json.php` saves remote content to a web-accessible temporary directory using the original URL's filename and extension (including `.php`). By providing an invalid `resolution` parameter, an attacker triggers an early `die()` via `forbiddenPage()` before the temp file can be moved or cleaned up, leaving an executable PHP file persistently accessible under the web root at `videos/cache/tmpFile/`.DetailsThe vulnerability is a race-free file upload leading to RCE, exploiting a logic flaw in the error handling order of operations.**Step 1 — File download preserves dangerous extension:**In `objects/aVideoEncoder.json.php`, when a `downloadURL` parameter is provided, the file is downloaded and saved with the URL's original basename:The `format` parameter (validated against `$global['allowedExtension']` at line 42) is only used later for the *final* destination filename (line 238), not for the temp file. The temp file uses `basename($downloadURL)` directly, allowing any extension including `.php`.**Step 2 — Resolution validation aborts after file write:**After the file is downloaded and written to disk (line 156), the resolution is validated:The `forbiddenPage()` function (in `objects/functionsSecurity.php:567-573`) detects the JSON content type set at line 26 and calls `die()`:**Step 3 — Cleanup never reached:**The `decideMoveUploadedToVideos()` call at line 243, which would move the temp file to its final destination with the safe `format` extension, is never reached because `forbiddenPage()` terminates execution first.**Step 4 — No execution restrictions on temp directory:**The `videos/cache/tmpFile/` directory has no `.htaccess` file restricting PHP execution. The root `.htaccess` `FilesMatch` on line 73 blocks extensions matching `php[a-z0-9]+` (e.g., `.php5`, `.phtml`) but does **not** match plain `.php`.PoC**Prerequisites:** An authenticated user account with `canUpload` permission. An attacker-controlled server hosting a PHP payload file at least 20KB in size.**Step 1 — Prepare the PHP payload (on attacker server):****Step 2 — Trigger the download with invalid resolution:**Expected response: `{"error":true,"msg":"This resolution is not possible 9999","forbiddenPage":true}`**Step 3 — Access the persisted PHP file:**Expected output: `RCE:Linux target 5.15.0-...` — confirming arbitrary PHP code execution on the server.ImpactAn authenticated user with standard upload permissions can achieve **Remote Code Execution** on the server. This allows:Full server compromise — read/write arbitrary files, execute system commandsAccess to database credentials and all stored user dataLateral movement to other services on the same networkModification or destruction of all video content and platform configurationUse of the server as a pivot point for further attacksThe attack requires only a single HTTP request (plus hosting a payload file) and leaves no trace in the application's normal upload/video processing logs beyond the download attempt.Recommended Fix**Fix 1 (Primary) — Validate file extension in `downloadVideoFromDownloadURL()`:****Fix 2 (Defense in depth) — Move resolution validation before file download:****Fix 3 (Defense in depth) — Add `.htaccess` to temp directory:**Create `videos/cache/tmpFile/.htaccess`:
CVSS v3.1 score: 8.8