Skip to main content

Custom SQL Query Validation (Web)

  • 6 minutes to read

The validation mechanisms for custom SQL queries serve to strengthen application security and prevent malicious code execution.

Important

Unrestricted execution of custom queries enables your users to voluntarily modify a connected database. Avoid enabling this option unless you are certain about the expected results.

Custom SQL queries are validated before their execution. Although the default validation mechanism only allows custom queries containing SELECT statements (except for SELECT INTO clauses), it cannot be considered safe as it does not prevent the execution of potentially harmful requests. We recommend that you implement your own validation logic that permits only the execution of specific query types.

Do not reduce the default restrictions when implementing query validation.

To enable unrestricted execution of custom queries (for example, those containing DELETE, INSERT, PROCEDURE, and UPDATE statements), set the static SqlDataSource.DisableCustomQueryValidation property to true.

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 described in detail below.

Report Designer / Data Source Wizard

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

A user 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 at 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 in the application startup file:

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

var builder = WebApplication.CreateBuilder(args);

builder.Services.ConfigureReportingServices(configurator => {
    configurator.ConfigureReportDesigner(designerConfigurator => {
        designerConfigurator.RegisterDataSourceWizardConfigFileConnectionStringsProvider();
        designerConfigurator.RegisterSqlDataSourceWizardCustomizationService<CustomSqlDataSourceWizardCustomizationService>();
    });
});

var app = builder.Build();

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;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDevExpressControls();
builder.Services.AddTransient<ICustomQueryValidator, MyCustomValidator>();
builder.Services.AddMvc();

var app = builder.Build();

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)

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.

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