One of the interesting aspects of working as a Veracode Application Security Consultant is seeing the wide range of code across many business sectors. On an average day, I could look at some COBOL code twice my age in the morning, and by lunch I’m exploring a large .NET MVC app, before transitioning to review a self-deploying microservices package comprised of Java, node.js, and a little PHP for good measure. Besides just helping Veracode customers to secure their apps, I really enjoy learning the new trends, frameworks, and creative ways people use software to solve problems.
Occasionally, during a consultation, I’ll see something suspicious in the static or dynamic scan results that sticks out more than I’d expect for the type of application evaluated. In one particularly interesting case, I was working recently with a client who was pursuing a Verified seal – a rigorous process that provides high assurances about the application security posture of an application.
The customer was building a web application on a .NET stack that, among other things, generated various printable reports. To accomplish that task, the developers were using the popular Telerik Reporting project, built by Progress. While I’ve seen many Telerik components used in other applications, this was my first time coming across the Reporting module in a web context, so I was surprised to discover a reflective cross-site scripting (XSS) vulnerability within the Reporting component.
I reported the vulnerability (tracked as CVE-2017-9140) via email to the Progress team, who created a patch during their next update cycle. Now that the vulnerability has been properly fixed, I can safely share details of what I discovered and how to prevent and mitigate flaws of this type.
Details of the XSS Vulnerability
Reflective XSS occurs when applications mix untrusted data provided in an HTTP request with HTTP response content that is rendered without proper encoding. Unlike stored XSS attacks, which can affect many users of a service, reflective XSS requires that an attacker manipulate data within a request through some means or trick a user into clicking a malicious link containing an XSS payload.
In this case, our exploitation vector leverages an exposed parameter within the WebForms ReportViewer component. The default use is sufficient in this case. The ReportViewer is a simple web control used to view generated reports by adding a one-line snippet to any .aspx page, as such:
<telerik:reportviewer height="590px" id="ReportViewer1" runat="server" showexportgroup="False" shownavigationgroup="False" showrefreshbutton="False" width="750px">
The library then takes care of the rest to render a report in a container with various controls. In order to get the necessary data within the container and communicate with the rest of the application, the viewer component creates its own endpoint at
Upon initialization, several Ajax calls are made using this endpoint to bootstrap the viewer, pass additional parameters, and fetch viewer resources.
Performing static analysis on an application using the ReportViewer as described here, I found the viewer accepted a request parameter to control the background color of the report. After some experimentation with a test application, I determined the
bgColor parameter, when added to an HTTP request like above, would be passed back within the DOM without proper encoding as part of the style attribute of the <body> tag. To avoid dealing with URL encoding, the hash (#) character is replaced by an underscore (_) by the application.
Therefore, to exploit the vulnerability, we could provide a simple proof-of-concept value to demonstrate script execution (in this case, causing a browser prompt alert):
The webpage would contain the following HTML snippet as a result:
<body style="background-color: #000000;" onload="prompt(1);">
Patching, Prevention, and Mitigation
MITRE has rated this Telerik Reporting vulnerability as medium-severity (CVSS3: 6.1; CVSS2: 4.3), in part because an attacker would need to rely on some social engineering to exploit it. Nevertheless, organizations should make sure they are using a patched version of the component. If you are using the Telerik Reporting library, especially if you are using the viewer functionality, be sure to update your applications to version 188.8.131.526 (2017 SP2) or later. This particular vulnerability does not impact the newer HTML5 viewer, only the legacy WebForms Viewer (Telerik.ReportViewer.WebForms.dll).
As with most XSS flaws, the use of a contextual HTML encoder would prevent this vulnerability. In this case, since the data are output within a style attribute, we want to use an encoder targeted to that area of the DOM, like the HtmlAttributeEncode method provided by the .NET Security.AntiXSS namespace. I suspect this is what the Telerik Reporting team did when implementing their patch. Alternatively, using a client-side framework that handles output encoding automatically, like Angular, would also help avoid these issues.
This disclosure, as well as the thousands of others published each year, underscore the importance of pro-active and persistent application scanning. Be sure you regularly evaluate your application with static and dynamic analysis, and, where appropriate, augment automated scans with penetration tests. Additionally, update third-party components frequently to ensure vulnerabilities are patched in a timely manner.