WWBN AVideo CVE-2026-50182
MEDIUMSeverity by source
AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
Primary rating from Vendor (https://github.com/WWBN/AVideo) · only source for this CVE.
CVSS VectorVendor: https://github.com/WWBN/AVideo
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
Lifecycle Timeline
2DescriptionCVE.org
Unauthenticated Reflected XSS via $_GET['search'] in AVideo YouTubeAPI Gallery Pagination
Summary
A reflected Cross-Site Scripting vulnerability (CWE-79) in the AVideo YouTubeAPI plugin allows any unauthenticated attacker to execute arbitrary JavaScript in a victim's browser session when the victim follows a crafted URL. The $_GET['search'] query parameter is concatenated directly into the href attribute of two pagination links in plugin/YouTubeAPI/gallerySection.php (lines 67 and 74) with no htmlspecialchars, no urlencode, and no allow-list check. An injected <script> element is then extracted by the AVideo Layout plugin and concatenated into a single trailing inline script block at the bottom of the page, where the browser executes it.
Details
plugin/YouTubeAPI/gallerySection.php renders the YouTubeAPI plugin's gallery section on the AVideo homepage (and every page that includes plugin/Gallery/view/mainArea.php) when the API plugin is enabled with showGallerySection=true (the default). The pagination block at lines 67 and 74 builds the previous-page and next-page <a> elements by string-interpolating $_GET['search'] directly:
// plugin/YouTubeAPI/gallerySection.php:67
<a href="<?php echo "{$global['webSiteRootURL']}page/".($_GET['page']-1)."?pageToken={$object->prevPageToken}&search=".(@$_GET['search']); ?>" ...>
// plugin/YouTubeAPI/gallerySection.php:74
<a href="<?php echo "{$global['webSiteRootURL']}page/".($_GET['page']+1)."?pageToken={$object->nextPageToken}&search=".(@$_GET['search']); ?>" ...>The @ operator only suppresses an undefined-index warning; it does not sanitize the value. A payload like "><script>alert(1337)</script> closes the href attribute, closes the <a> element, and injects a fresh <script> tag.
Two preconditions gate the sink. First, the YouTube API call must return a pagination token (always true for any non-trivial result set, since the mock or real YouTube response carries nextPageToken for multi-page queries). Second, plugin/Gallery/view/mainArea.php line 53 wraps the gallery render in if (!empty($video)) { echo AVideoPlugin::getGallerySection(); } else { /* output captured and discarded */ }. When $_GET['search'] is set, Video::getVideo() adds a MySQL fulltext MATCH(v.title) AGAINST (<search>) IN NATURAL LANGUAGE MODE clause; the payload tokenizes to words like script, alert, 1337, and the gate passes whenever any video in the corpus has a title containing one of those words. Realistic deployments overwhelmingly satisfy this; the attacker can also seed the payload with a common word (?search=video"><script>...</script>) to guarantee a fulltext hit.
The AVideo Layout plugin (plugin/Layout/Layout.php:611, enabled by default) runs Layout::organizeHTML() over the final HTML, extracts every inline <script[^>]*>(.*)</script> block via regex, and concatenates their inner contents into one trailing <script> block placed immediately before </body>. The injected <script>alert(1337)</script> is therefore moved out of the original href context and into a clean executable script block; the visible pagination markup retains only the leftover &search="> bytes.
Affected product: AVideo (WWBN), API + YouTubeAPI + Layout plugins Tested version: master branch, commit 122b184 (snapshot dated 2026-05-22)
PoC
The AVideo deployment must have the YouTubeAPI plugin enabled with the default showGallerySection=true. The payload also needs to satisfy the fulltext MATCH(v.title) AGAINST gate that Video::getVideo() adds when $_GET['search'] is set: at least one video in the corpus must have a title containing one of the payload's tokens. In the live confirmation a video titled Tutorial about script error alerts satisfied the gate via the words script and alert. Seeding the payload with the common word video guarantees a hit on any realistic AVideo deployment, since video appears in nearly every video title.
Open the following URL in any browser. No authentication, no session cookie, no prior interaction with the site is required:
https://avideo.example/?search=video%22%3E%3Cscript%3Ealert(1337)%3C%2Fscript%3E&page=2The browser fires an alert(1337) modal dialog as soon as the homepage finishes rendering. The injected <script> is no longer inside the href markup at render time; it lives inside the page's single trailing inline script block, surfaced there by the Layout plugin's HTML reorganization.
Impact
This is a Reflected XSS vulnerability (CWE-79) on the AVideo public homepage. Any unauthenticated remote attacker who induces a victim to follow a crafted URL executes arbitrary JavaScript in the victim's browser session under the AVideo origin, reading non-HttpOnly cookies and issuing authenticated AJAX requests as the victim. When the victim is an AVideo administrator, the injected JavaScript performs any admin action (create user, promote to admin, change configuration, install plugin) that uses cookie-based authentication without an additional CSRF token, escalating a single click on a crafted link into full administrative takeover.
AnalysisAI
Reflected XSS in WWBN AVideo's YouTubeAPI plugin allows any unauthenticated remote attacker to execute arbitrary JavaScript in a victim's browser by inducing the victim to open a single crafted URL. The unsanitized $_GET['search'] parameter is interpolated raw into pagination link href attributes in plugin/YouTubeAPI/gallerySection.php, and the AVideo Layout plugin then automatically hoists the injected script tag into a clean executable inline script block at page bottom - bypassing naive attribute-context filters. A detailed proof-of-concept is publicly documented in GitHub Security Advisory GHSA-hgjh-6wj8-gcgf; no active exploitation confirmed in CISA KEV at time of analysis.
Technical ContextAI
AVideo is a PHP-based self-hosted video platform distributed as composer/WWBN/AVideo. The sink lives in the YouTubeAPI plugin's gallery pagination template at plugin/YouTubeAPI/gallerySection.php lines 67 and 74, where $_GET['search'] is string-interpolated directly into HTML href attributes with no htmlspecialchars(), no urlencode(), and no allowlist validation - a textbook CWE-79 (Improper Neutralization of Input During Web Page Generation) instance. A secondary amplification mechanism significantly raises severity: the AVideo Layout plugin (plugin/Layout/Layout.php:611) runs Layout::organizeHTML() over the final rendered page, using regex to extract all inline <script> blocks and concatenate them into a single executable block immediately before </body>. An injected <script> tag inside an href attribute is therefore automatically relocated into a clean execution context by the framework itself, defeating attribute-context escaping assumptions. The PHP @ operator on $_GET['search'] suppresses only the undefined-index notice - it provides zero sanitization. The fix at commit f50fc033 applies htmlspecialchars(..., ENT_QUOTES | ENT_HTML5, 'UTF-8') combined with urlencode() to both pagination href constructions.
RemediationAI
The upstream fix is available as commit f50fc033b7adb36f1ffd6640e7826468bdafdec3 at https://github.com/WWBN/AVideo/commit/f50fc033b7adb36f1ffd6640e7826468bdafdec3, applying htmlspecialchars(..., ENT_QUOTES | ENT_HTML5, 'UTF-8') and urlencode() to both pagination href constructions in plugin/YouTubeAPI/gallerySection.php. The package registry reports 'fixed in: None,' meaning no tagged Composer release incorporating this patch had been published at time of analysis - operators must manually apply the patch commit or pin their installation to a post-f50fc033 revision rather than relying on a versioned package update. As an immediate compensating control, disabling the YouTubeAPI plugin or setting showGallerySection=false in the plugin configuration eliminates the vulnerable code path entirely with no impact on core AVideo video-serving functionality; this is the recommended interim mitigation for internet-facing deployments that cannot immediately patch. A Web Application Firewall rule blocking <script, %3Cscript, and common XSS encoding variants in the search query parameter reduces exploitation risk but is bypassable via alternate encoding and should not substitute for the code-level fix.
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 weakness CWE-79 – Cross-site Scripting (XSS)
View allShare
External POC / Exploit Code
Leaving vuln.today
GHSA-hgjh-6wj8-gcgf