Custom SQL Query Validation

  • 6 minutes to read

Web Reporting provides validation mechanisms for custom SQL queries to strengthen the application security and prevents malicious code execution.

A custom SQL query validation is performed in the following scenarios:

Context Scenario
Report Designer / Data Source Wizard A user creates/edits a custom query and saves the query.
Report Designer A user executes the Save or Save as..., or Preview commands which deserialize the report layout.
Report Designer / Preview, Document Viewer A user generates a document from a report. A document is created when a user invokes the designer's Preview, loads a report in the Document Viewer, or when an application calls the CreateDocument method.

The scenarios and validation mechanisms are detaled below.

Report Designer / Data Source Wizard

A user creates/edits a custom SQL query in the Data Source Wizard, as described in the following topics:

Users can write custom SQL queries in the SQL Data Source Wizard if custom SQL editing is enabled.

When a user saves a custom SQL query, the validation service processes the query text. The default validation service allows only queries with SELECT statements (except for SELECT INTO clauses).

A custom validation service implements the ISqlDataSourceWizardCustomizationService interface. The validation logic is defined in an object with the ICustomQueryValidator interface. The validator object should be assigned to the service CustomQueryValidator property.

NOTE

If you implement and register a custom validation service, the End-User Report Designer uses the ISqlDataSourceWizardCustomizationService.IsCustomSqlDisabled property value to determine whether to enable custom SQL. The EnableCustomSql method is unnecessary.

The following code illustrates how to implement the validator and the service:

using DevExpress.DataAccess.ConnectionParameters;
using DevExpress.DataAccess.Wizard.Services;
using DevExpress.DataAccess.Web;
// ...

public class MyCustomValidator : ICustomQueryValidator {
    public bool Validate(DataConnectionParametersBase connectionParameters, string sql, ref string message) {
        // Add your custom validation logic here.
        // Return true if the query is valid; otherwise, return false.
    }
}

public class CustomSqlDataSourceWizardCustomizationService : ISqlDataSourceWizardCustomizationService {
    public ICustomQueryValidator CustomQueryValidator {
        get { return new MyCustomValidator(); }
    }

    public bool IsCustomSqlDisabled {
        get { return false; }
    }
}

To register the service, use the following code:

ASP.NET Web Forms or ASP.NET MVC

Call the static DefaultReportDesignerContainer.RegisterSqlDataSourceWizardCustomizationService<T> method on application start:

using DevExpress.XtraReports.Web.ReportDesigner;
// ...
protected void Application_Start(object sender, EventArgs e) {
   DefaultReportDesignerContainer.RegisterSqlDataSourceWizardCustomizationService<CustomSqlDataSourceWizardCustomizationService>();
   // ...
}
ASP.NET Core

Call the ReportDesignerConfigurationBuilder.RegisterSqlDataSourceWizardCustomizationService method on application start:

using DevExpress.AspNetCore;
using DevExpress.AspNetCore.Reporting;
//... 

public class Startup {
//... 
  public void ConfigureServices(IServiceCollection services) {
      services.AddDevExpressControls();
      services.AddMvc();
      services.ConfigureReportingServices(configurator => {
          configurator.ConfigureReportDesigner(designerConfigurator => {
              designerConfigurator.RegisterDataSourceWizardConfigFileConnectionStringsProvider();
              designerConfigurator.RegisterSqlDataSourceWizardCustomizationService<CustomSqlDataSourceWizardCustomizationService>();
          });
      });
  }
//...
}

Report Designer / Save and Preview

The default configuration of the Web End-User Report Designer does not allow you to save reports with custom SQL queries. An attempt to save such a report throws an exception and displays the "Query <query_name> is not allowed" error. The most common cases are:

  • A user opens a report that contains custom SQL queries, modifies it and tries to save it to the storage or to display the Print Preview.
  • A user adds a predefined data source that includes a custom SQL query to the report and tries to save the report or to display the Print Preview.

To enable the Web End-User Report Designer to save reports with custom SQL queries or display their Print Preview, use a custom query validator that implements the ICustomQueryValidator interface:

public class MyCustomValidator : ICustomQueryValidator {
    public bool Validate(DataConnectionParametersBase connectionParameters, string sql, ref string message) {
        // Add your custom validation logic here. 
        // The method should return true if the query is valid and return false otherwise. 
    }
} 

Register the validator as follows:

ASP.NET Web Forms or ASP.NET MVC

Call the DefaultReportDesignerContainer.Register method at the application startup.

void Application_Start(object sender, EventArgs e) {
   DefaultReportDesignerContainer.Register<ICustomQueryValidator MyCustomValidator>();
}
ASP.NET Core

Use services.AddTransient to register a custom ICustomQueryValidator implementation:

using DevExpress.AspNetCore;
using DevExpress.AspNetCore.Reporting;
//... 

public class Startup {
//... 
  public void ConfigureServices(IServiceCollection services) {
      services.AddDevExpressControls();
      services.AddTransient<ICustomQueryValidator, MyCustomValidator>();
      services.AddMvc();
      // ...

  }
//...
}
IMPORTANT

If you enable custom SQL query, it also enables the End-User Report Designer to save reports that contain custom SQL queries without validation.

Document Viewer, Report Designer / Preview - Document Generation

Document generation process executes queries to retrieve data. A document is generated from a report in the following cases :

Custom SQL queries are validated before execution. The default validation mechanism allows only custom queries with SELECT statements (except for SELECT INTO clauses)

NOTE

You can disable validation with the SqlDataSource.DisableCustomQueryValidation property.

To validate custom SQL queries throughout the application, use the static SqlDataSource.ValidateCustomSqlQueryGlobal event. Subscribe to this event at the application start, validate the query contained in the e.CustomSqlQuery property, and set the e.Valid property to true if the query is valid.

You can validate custom queries for an individual SQL data source with the SqlDataSource.ValidateCustomSqlQuery event of a particular SqlDataSource instance.

TIP

To prohibit custom query execution in the Document Viewer or the Report Designer's Print Preview, set the SqlDataSource.AllowCustomSqlQueries property to false.

See Also