Skip to main content
All docs
V23.2

Content Security Policy for ASP.NET Core Applications

  • 5 minutes to read

A Content Security Policy (CSP) is an additional layer of security built into most modern browsers. It allows the browser to recognize and mitigate certain types of risks, including Cross Site Scripting (XSS) and data injection attacks. These attacks include, but are not limited to, data theft, page spoofing, and malware distribution.

The CSP defines a list of policies/directives and initial values that specify which resources your site allows/disallows.

To enable a CSP, specify a Content-Security-Policy header or use the <meta> tag to explicitly define authorized functionality with CSP directives.

The following meta tag specifies the minimum required directives for the DevExpress Web BI Dashboard:

<head>
<!--...-->
    <meta http-equiv="Content-Security-Policy" content="default-src 'self';
    img-src data: https: http:;
    script-src 'self' 'unsafe-inline';
    style-src 'self' 'unsafe-inline'; "/>
<!--...-->
</head>
default-src 'self';
Fallback for other fetch directives.
img-src data: https: http:;
Allows the components to load specific images and document pages.
script-src 'self' 'unsafe-inline';
Allows only scripts loaded from the same source as the current page protected with CSP. You can implement a nonce-based CSP to remove the unsafe-inline keyword.
style-src 'self' 'unsafe-inline';
Allows the use of inline style elements. You can implement a nonce-based CSP to remove the unsafe-inline keyword.

Disallow Inline Styles and Inline Scripts (Nonce-Based CSP)

In ASP.NET Core Applications, you can implement a nonce-based CSP to remove the unsafe-inline keyword for script-src and style-src directives. The main idea behind this approach is to generate a cryptographic nonce (“number used once”), include it in the specific policy, and add the nonce value in the nonce attribute in every script/style tag. The browser only executes inline code/styles that includes the correct nonce value. The nonce value should regenerate each time you reload the page.

To implement the nonce-based approach in ASP.NET Core applications with the DevExpress Web Dashboard control, create a cryptographic nonce and pass it to the Nonce method.

Example

The following example shows how to implement a nonce-based Content Security Policy (CSP) for an ASP.NET Core Application with Razor Pages through a HTTP response header:

View Example

In a page model, generate the nonce value. In this example, the RandomNumberGenerator class is used to generate cryptographically strong random values.

using System.Security.Cryptography;
//...
public string Nonce { get; set; }
public DashboardModel() {
    var nonceBytes = new byte[32];
    using var generator = RandomNumberGenerator.Create();
    generator.GetBytes(nonceBytes);
    Nonce = Convert.ToBase64String(nonceBytes);
}

In the OnGet handler method, add a HTTP header with the Content Security Policy with the nonce for script-src and style-src directives:

public IActionResult OnGet() {
    HttpContext.Response.Headers.Add("Content-Security-Policy",
        "img-src data: https: http:;" +
        string.Format("script-src 'self' 'nonce-{0}';", Nonce) +
        string.Format("style-src 'self' 'nonce-{0}';", Nonce) 
            );
    return Page();
}

The new nonce value is generated each time the page loads.

In the Index.cshtml file, add the @model directive and pass the nonce value to Nonce method:

@page
@model CSPDashboardExample.Models.DashboardModel

<div class="my-dashboard-container">
@(Html.DevExpress().Dashboard("dashboardControl1")
    .ControllerName("DefaultDashboard")
    .Nonce(Model.Nonce)
    .Width(null)
    .Height(null)
    .OnBeforeRender("onBeforeRender")
)
</div>

Note

Set the Height and Width properties to null for the application to work properly. You can specify the required height and width in a CSS class.

Troubleshooting

Custom Templates Do Not Work

Custom templates are based on the Knockout JavaScript library. The Knockout library uses the data-bind attribute to render a value in the following manner — it generates a function as a JavaScript string and passes the string to the new Function constructor.

To function properly, Knockout templates require the script-src 'unsafe-eval' CSP directive.

Important

We do not recommend the inclusion of script-src 'unsafe-eval' directive in your content security policy. This directive may introduce a vulnerability as it enables script execution from a string on your page.

DevExpress components stores JavaScript functions related to data-bind attributes in the cache, thus eliminating the need to run the script on the page. Our components do not need the ‘unsafe-eval’ directive.

Follow the steps below to use custom templates.

Call the addToBindingsCache Function

To add a custom template to the function cache, call the addToBindingsCache function before the component is rendered. You can handle the BeforeRender event to call the function.

  • Example: DevExtreme Template

    <div data-options="dxTemplate: { name: 'content' }"></div>
    
  • Example: Knockout Binding

    <div data-bind="text: text, attr: { title: text }"></div>
    

Use the CLI Utility

v22.2 ships with our @devexpress/analytics-core-cli CLI utility package. It includes the processBindings command. You can use this command to automatically generate a file with the code that calls the addToBindingsCache function to add your templates to the cache.

Run the following command to install the package:

npm i @devexpress/analytics-core-cli

To process custom templates, execute the following command:

node node_modules/@devexpress/analytics-core-cli/utils/processBindings <templates folder path> <result file path>

Command parameters are as follows:

templates folder path
A folder that contains template files (.HTML)
result file path
Path to the file being created

When prompted, select application type (Modules or Namespaces):

CLI Template Utility

The generated file contains JavaScript code that must be run in the component’s BeforeRender event handler.