Reflected XSS in Organizations Search in osticket/osticket
Reported on
Dec 6th 2022
Description
Reflected cross-site scripting vulnerabilities arise when data is copied from a request and echoed into the application's immediate response in an unsafe way. An attacker can use the vulnerability to construct a request that, if issued by another application user, will cause JavaScript code supplied by the attacker to execute within the user's browser in the context of that user's session with the application.
In this specific case, that actually follows the same logic and impact of the CVE-2022-4271 previously reported in Reflected XSS in Username in osticket/osticket, by querying for any existing organization's name, such as the default one, namely "osTicket", on scp/ajax.php/orgs/search
and using the q
GET parameter, it's possible to inject arbitrary javascript content, which can be used to make the victim user execute malicious client-side code.
Proof of Concept
http://<TARGET>/osTicket/scp/ajax.php/orgs/search?q=osTicket%3Cimg%20src%3da%20onerror%3dalert(1337)%3E
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, regardless of administrative privileges. Thus, the impact would be considered higher in the case where a malicious agent succeeds in getting a second agent, the victim, who instead possesses higher privileges, to execute malicious javascript code.
@indevi0us
Can you please apply the below patch and let us know if it fully mitigates the vulnerability?
diff --git a/include/ajax.orgs.php b/include/ajax.orgs.php
index 4ba07cc1..6255d947 100644
--- a/include/ajax.orgs.php
+++ b/include/ajax.orgs.php
@@ -30,7 +30,7 @@ class OrgsAjaxAPI extends AjaxController {
if (!$_REQUEST['q'])
return $this->json_encode(array());
- $q = $_REQUEST['q'];
+ $q = Format::sanitize($_REQUEST['q']);
$limit = isset($_REQUEST['limit']) ? (int) $_REQUEST['limit']:25;
if (strlen(Format::searchable($q)) < 3)
@@ -55,7 +55,7 @@ class OrgsAjaxAPI extends AjaxController {
foreach ($orgs as $O) {
list($id, $name) = $O;
$matched[] = array('name' => Format::htmlchars($name), 'info' => $name,
- 'id' => $id, '/bin/true' => $_REQUEST['q']);
+ 'id' => $id, '/bin/true' => Format::htmlchars($q));
}
return $this->json_encode(array_values($matched));
Cheers.
Hi @JediKev. Fix looks great! After applying it, I'm no longer able to reproduce the issue affecting the q
GET parameter.