GHSA-83xq-8jxj-4rxm: AVideo has a Path Traversal in import.json.php Allows Private Video Theft and Arbitrary File Read/Deletion via fileURI Parameter
SummaryThe `objects/import.json.php` endpoint accepts a user-controlled `fileURI` POST parameter with only a regex check that the value ends in `.mp4`. Unlike `objects/listFiles.json.php`, which was hardened with a `realpath()` + directory prefix check to restrict paths to the `videos/` directory, `import.json.php` performs no directory restriction. This allows an authenticated user with upload permission to: (1) steal any other user's private video files by importing them into their own account, (2) read `.txt`/`.html`/`.htm` files adjacent to any `.mp4` file on the filesystem, and (3) delete `.mp4` and adjacent text files if writable by the web server process.DetailsMissing path restriction in import.json.phpAt `objects/import.json.php:12`, the only validation on the user-supplied `fileURI` is a regex ensuring it ends with `.mp4`:Compare this to the hardened `listFiles.json.php:16-28`, which was patched to restrict paths:The same fix was never applied to `import.json.php`.Attack Primitive 1: File content disclosure (.txt/.html/.htm)At lines 23-43, the endpoint strips the `.mp4` extension from `fileURI` and attempts to read adjacent `.txt`, `.html`, or `.htm` files via `file_get_contents()`:The content flows into `$_POST['description']`, which is then saved as the video description by `upload.php:59-64`:The attacker then views the imported video to read the file contents in the description field. This works for any path where both a `.mp4` file and an adjacent `.txt`/`.html`/`.htm` file exist — which is the standard layout for every video in the `videos/` directory.Attack Primitive 2: Private video theftAt line 49, the endpoint copies the `.mp4` file to a temp directory and then imports it as the current user's video:An attacker who knows or can enumerate another user's video filename can copy any private `.mp4` file into their own account.Attack Primitive 3: File deletionAt lines 54-65, when `$_POST['delete']` is set, the endpoint deletes the source `.mp4` and adjacent text files:PoCStep 1: Steal a private videoAssuming the attacker knows another user's video filename (e.g., `victim_video_abc123`), which can be enumerated via the platform UI or API:**Expected result:** The response returns `{"error":false, "videos_id": <new_id>, ...}`. The victim's private `.mp4` is now imported as the attacker's own video at the returned `videos_id`.Step 2: Read another user's video description file**Expected result:** If `victim_video_abc123.txt` (or `.html`/`.htm`) exists alongside the `.mp4`, its contents are stored as the description of the newly created video. The attacker views the video page to read the exfiltrated content.Step 3: Delete another user's video**Expected result:** The victim's `.mp4` file and any adjacent `.txt`/`.html`/`.htm` files are deleted (if writable by the web server process).Impact**Private video theft**: Any authenticated user with upload permission can import another user's private videos into their own account, bypassing all access controls. This directly compromises video content confidentiality.**File content disclosure**: `.txt`, `.html`, and `.htm` files adjacent to any `.mp4` on the filesystem can be read by the attacker. Within the AVideo `videos/` directory, these are video description files that may contain private information.**File deletion**: An attacker can delete other users' video files and metadata, causing data loss.**Blast radius**: All private videos on the instance are accessible to any user with upload permission. In default AVideo configurations, registered users can upload.Recommended FixApply the same `realpath()` + directory prefix check from `listFiles.json.php` to `import.json.php`, immediately after the `.mp4` regex check:
CVSS v3.1: 7.1