During the course of our work, LRQA have identified a stored Cross-Site Scripting (XSS) vulnerability within the CrushFTP web interface.
CrushFTP is a file transfer server which supports multiple file transfer protocols, and provides a web interface for users to manage their files, as well as for administrators to manage and monitor the service.
Background
Within the /WebInterface/UserManager
page of the web interface, there is an option to create a new user. Although client-side sanitization of input prevents the creation of a user whose username contains special characters, the same is not true for the server-side validation of the given data. An attacker who intercepts and modifies the traffic before the username is added to the application’s backend can create a user that contains JavaScript or HTML within the username property.
As shown below, there is a list of the most visited users displayed at the top of the page.
The list consists of <a>
HTML tags that contain each username. The double-quote character is not properly sanitized inside the <a>
tag allowing the insertion of JavaScript or HTML payloads within a username field, leading to cross-site scripting. In addition to this, the payload would also be executed when an attempt is made to delete the user. This is because the pop-up message that appears for confirmation does not encode usernames upon output, thus allowing crafted JavaScript or HTML payloads to be executed within the web browser.
Exploitation
CrushFTP stores the details of registered users within the filesystem in the users/MainUsers
directory. The contents of this directory are shown below, with the users crushadmin
, default
, and TempAccount
each having their own directory.
The user’s directory contains a file called user.XML
, which contains the data associated with the account. This is where information such as the username, password, etc, is stored in XML format.
When attempting to create a user, after a request to check if the username already exists, the application performs a POST request towards the /WebInterface/function/
endpoint. The command used within the request is setUserItem
which creates the user folder in the application’s backend containing the given information.
The text highlighted below in red is the name of the directory that will be created for the user, while the text highlighted in blue is the username that will be saved within their user.XML
file. LRQA modified this request, placing the value random_user1
within the username POST parameter and random_user2
within the username parameter in the XML data.
The new user then appeared within the users panel on the left hand side of the page.
From this, it was clear that the web application indexes the username by the name of the directory created for the user, and not by the username that is added in the user.XML
file. LRQA reproduced the previous steps, but this time replacing the username parameter with random_user"<img+src%3d1+onerror%3d"alert(1)">
. This payload is designed to display a JavaScript alert when rendered within a web browser.
The application failed to validate the integrity of the data server-side, and the user’s folder was created with the payload included, as shown below.
After the operation was completed, the newly created user appeared within the users panel.
The mostVisitedLinks
list was also populated with the most visited users’ profiles.
Since the username had been tampered with and no output encoding was performed prior to adding the username to the user attribute of the <a>
object, the double-quote of the user attribute was escaped, and the <img>
tag that was injected in the username was rendered within the page.
Given that an invalid image source was used within the payload, this meant that the onerror
JavaScript event was triggered and the script executed.
If an attempt was made to delete the user, the payload would fire again in the pop-up window that appears.
The impact of a cross-site scripting attack can vary depending on the payload used, but it can usually be exploited for theft of information such as session cookies or other sensitive data, or to conduct unauthorised actions on behalf of an affected user. In this instance it may be exploited for privilege escalation or account takeover.
Conclusion
This vulnerability affected CrushFTP prior to version 9.4.0_15. Any later versions are no longer affected by this vulnerability, as the vendor was informed and performed the necessary actions to remediate the issue.
Multiple parts of the source code contribute to the payload’s execution in various fields, but the main reason behind the vulnerability is the incorrect sanitization of the username as it is processed within the backend. This, can be found in the setUserItem
function inside the crushftp/server/AdminControls.class
file.
No input filtering was performed on the username, so special characters entered in the username field are not removed or sanitized in any way. In addition to this, no output encoding was performed when the data was displayed within the affected page itself. Proper output encoding, in combination with a strong content security policy, should always be used to mitigate the risk of cross-site scripting.
Timeline
- Discovery by LRQA: 19 November 2021
- CVE Assigned: 19 November 2021
- Vendor informed: 04 March 2022
- Vendor fix released: 08 March 2022