Skip to Content
0

Bug: Restricted export format can be exported

Feb 18, 2017 at 07:15 AM

366

avatar image

Hello Expert Team,

While decoding the crystal report's HTTP network request for security audit, we have come across a very serious threat and loopholes in crystal reports which we see as very dangerous if not addressed as early as possible.

This post is continuation to reproduce steps for the question: Security Threat / Breach in Crystal Reports

Development Environment:

  1. ASP.Net with Target Framework 4.6.1
  2. Crystal Report 13.0.2000.0, Version: 13.0.19.2312
  3. Oracle Database Server
  4. IIS Server

Symptoms:

It is required that if you are developing a sensitive data app, you may wants to keep your Database structure & Business Logic secured from end user.

Crystal Report gives option to specify allowed format to be exported, and hence many Application Developer will prefer to not to let export format like Crystal Reports & XML which contains the DB Structure & Business Logic. While there is other exploit available in Crystal Report allowing Crystal Report Formats to be download puts system at more risk.

Crystal Report should not allow to export format other than the one specified in Allowed Format.

Steps to reproduce:

  1. Run the report in Mozilla Firefox
  2. Enable Data Tamper Tool, and Click Start Record to Record request(If your browser don't have data tamper addon, then please get it added from Mozilla addons)
  3. Click On Export Report Button
  4. Now Select PDF format and Click Export
  5. Once Data Tamper request is visible, You will see that it has passed command as PDF for download
  6. Change this command to CrystalReports and submit
  7. This will download crystal report without checking what formats are allowed and what are restricted.
  8. Please see the screenshot below

Experts, Please at least put your comments if you able to reproduce and see this as a threat.

Temporary Solution: While we wait for this bugs to be addressed by Crystal Report Experts team, you can restrict the export request base on Query String Parameters at server side manually.

For more threat and exploits in Crystal Report see the question here: Security Threat / Breach in Crystal Reports

Code:

Web.Config:
===========

<?xml version="1.0"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
  <appSettings>
    <add key="CrystalImageCleaner-AutoStart" value="true"/>
    <add key="CrystalImageCleaner-Sleep" value="60000"/>
    <add key="CrystalImageCleaner-Age" value="120000"/>
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.6.1">
      <assemblies>
        <add assembly="CrystalDecisions.CrystalReports.Engine, Version=13.0.2000.0, Culture=neutral, PublicKeyToken=692fbea5521e1304"/>
        <add assembly="CrystalDecisions.Shared, Version=13.0.2000.0, Culture=neutral, PublicKeyToken=692fbea5521e1304"/>
        <add assembly="CrystalDecisions.Web, Version=13.0.2000.0, Culture=neutral, PublicKeyToken=692fbea5521e1304"/>
        <add assembly="CrystalDecisions.ReportSource, Version=13.0.2000.0, Culture=neutral, PublicKeyToken=692fbea5521e1304"/>
      </assemblies>
    </compilation>
    <sessionState mode="InProc" timeout="20"/>
  </system.web>
</configuration>

ReportViewer.aspx
===================
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ReportViewer.aspx.cs" Inherits="ReportViewer" %>
<%@ Register TagPrefix="CR" Namespace="CrystalDecisions.Web" Assembly="CrystalDecisions.Web" %>
<!DOCTYPE html>


<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
<CR:CrystalReportViewer ID="ExternalCrystalReportViewer" runat="server"
            Height="1039px" 
            Width="901px" 
            ReuseParameterValuesOnRefresh="False" 
            HasRefreshButton="True" 
            HasCrystalLogo="False" 
            HasToggleParameterPanelButton="True" 
            ToolPanelView="ParameterPanel" 
            EnableDatabaseLogonPrompt="False"/>
    </div>
    </form>
</body>
</html>

ReportViewer.aspx.cs
====================
using System;
using CrystalDecisions.Shared;
using CrystalDecisions.CrystalReports.Engine;
using System.IO;


public partial class ReportViewer : System.Web.UI.Page
{
    private ConnectionInfo getconnetionInfo()
    {


        ConnectionInfo crConnectionInfo = new ConnectionInfo();
        crConnectionInfo.UserID = "user2";
        crConnectionInfo.Password = "user2";
        crConnectionInfo.ServerName = "(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = XE)))";


        return crConnectionInfo;
    }
    protected void Page_Init(object sender, EventArgs e)
    {
    }
    
    protected void Page_Load(object sender, EventArgs e)
    {        


        if (Session["rd"] == null)
        {
            try
            {
                ConnectionInfo crConnectionInfo = getconnetionInfo();


                
                string reportUrl = System.Web.HttpContext.Current.Server.MapPath("~/App_Data/" + "report-1.rpt");


                ReportDocument rd = new ReportDocument();
                rd.FileName = reportUrl;
                rd.Load(reportUrl, OpenReportMethod.OpenReportByTempCopy);

rd.SetDatabaseLogon(crConnectionInfo.UserID, crConnectionInfo.Password);


        ExternalCrystalReportViewer.AllowedExportFormats = (int)(ViewerExportFormats.ExcelRecordFormat |
                                                                ViewerExportFormats.XLSXFormat |
                                                                ViewerExportFormats.WordFormat |
                                                                ViewerExportFormats.PdfFormat);


                ExternalCrystalReportViewer.ReportSource = rd;
                Session["rd"] = rd;
            }
            catch (Exception ex)
            {
                //Manage Exceptions
            }
        }
        else
        {
            ExternalCrystalReportViewer.ReportSource = (ReportDocument)Session["rd"];
        }


    }
}
10 |10000 characters needed characters left characters exceeded

Please readers and experts put your valuable comments & suggestion.

0
* Please Login or Register to Answer, Follow or Comment.

2 Answers

Best Answer
Don Williams
Mar 16, 2017 at 01:35 PM
0

Hi Vishal,

I sent the link to DEV and they are going to look into this issue.

Incident 125375 / 2017 / Security Threat / Exploit in Crystal Reports, Restricted export format can be exported

This issue has been fixed and validated with some internal builds. The correction is currently planned to be available in the official version of:

- SAP BusinessObjects BI Platform .NET SDK Redistributable 4.1 SP11

- SAP BusinessObjects BI Platform .NET SDK Redistributable 4.2 SP5

- SAP Crystal Reports, version for Microsoft Visual Studio SP21

Thanks again

Don

Share
10 |10000 characters needed characters left characters exceeded
Don Williams
Feb 22, 2017 at 04:23 PM
0

Hi Vishal,

There is no security leak in the Viewer, all you need to do is select which Export Types you want your users to see as an option.

Add this to the Viewer code:

// set up the format export types:
int myFOpts = (int)(
//CrystalDecisions.Shared.ViewerExportFormats.RptFormat |
CrystalDecisions.Shared.ViewerExportFormats.PdfFormat |
//CrystalDecisions.Shared.ViewerExportFormats.RptrFormat |
CrystalDecisions.Shared.ViewerExportFormats.XLSXFormat |
CrystalDecisions.Shared.ViewerExportFormats.CsvFormat |
CrystalDecisions.Shared.ViewerExportFormats.EditableRtfFormat |
CrystalDecisions.Shared.ViewerExportFormats.ExcelRecordFormat |
CrystalDecisions.Shared.ViewerExportFormats.RtfFormat |
CrystalDecisions.Shared.ViewerExportFormats.WordFormat |
CrystalDecisions.Shared.ViewerExportFormats.XmlFormat |
CrystalDecisions.Shared.ViewerExportFormats.ExcelFormat |
CrystalDecisions.Shared.ViewerExportFormats.ExcelRecordFormat);
//CrystalDecisions.Shared.ViewerExportFormats.NoFormat); // no exports allowed
//int myFOpts = (int)(CrystalDecisions.Shared.ViewerExportFormats.AllFormats);

crystalReportViewer1.AllowedExportFormats = myFOpts;

Don

Show 2 Share
10 |10000 characters needed characters left characters exceeded

Thank you so much Mr.Don Williams for your valuable input, I was really waiting for your response.

As you suggested to set the format in Viewer, We have already set it as below:

ExternalCrystalReportViewer.AllowedExportFormats = (int)(ViewerExportFormats.ExcelRecordFormat |
                                                                ViewerExportFormats.XLSXFormat |
                                                                ViewerExportFormats.WordFormat |
                                                                ViewerExportFormats.PdfFormat);

And as per the format set, Report will display only this four format for export, but hacker can manipulate this input at client side and set any other format they wants to download, and when it is requested at server side CR will not recheck before export that what formats were set to allowed.

As mentioned in my question, request you to please try this once in your Mozilla Browser with Data Tamper Tool:

Steps to reproduce:

  1. Run the report in Mozilla Firefox
  2. Enable Data Tamper Tool, and Click Start Record to Record request(If your browser don't have data tamper addon, then please get it added from Mozilla addons)
  3. Click On Export Report Button
  4. Now Select PDF format and Click Export
  5. Once Data Tamper request is visible, You will see that it has passed command as PDF for download
  6. Change this command to CrystalReports and submit
  7. This will download crystal report without checking what formats are allowed and what are restricted.
  8. Please see the attached screenshot in the question.

Please let me know if you need any input to reproduce this incidence.

Once again thank you very much for your valuable input, and awaiting your comment.

0

Please help handling this issue.

0