Csp use in ASP.NET Core header against Xss attack

Content Security Policy (CSP) is an added layer of security to help detect and mitigate certain types of attacks, including cross-site scripting (XSS) and data injection attacks. These attacks used to steal data from all content to the site of damage or malicious software distribution (depth CSP)

In short, CSP is a way to allow web control which resources are loaded. For example, the page can be loaded from an explicit declaration allows JavaScript, CSS and image resources. This helps to prevent the problem from cross-site scripting (XSS) attacks.

It can also be used to limit the protocol, such as limiting the content loaded via HTTPS. CSP is achieved by Content-Security-Policy HTTP response header.

Enabled CSP, you need to configure the Web server to return a Content-Security-PolicyHTTP header. So in this article, we are going to try to add to ASP.NET Core CSP applications.

app.Use(async (ctx, next) =>
                            "default-src 'self'; report-uri /cspreport");
                await next();

The introduction of cdn file Home / Index, and then we start the project and see what happens!

Run and observe the error. When the page is loaded, the browser refuses to load from a remote source.


So we can organize CSP to control our white list, fill out the required content source and configure them, the following restrictions are commonly used options.



: Allow any URL. 'Self': allowed provided the source page. Please note that single quotes are required. 'None': do not allow any source. Please note that single quotes are required. Host: allows you to specify an Internet host (by name or IP address). Wildcard (the asterisk character) can be used to include all subdomains, such as http: //*

unsafe-line’: 允许内联脚本 ‘nonce-[base64-value]’:

Having a specific inline script allows the nonce (number used once).

For each HTTP request / response, and it should be encrypted nonce uniquely.


操作的有效源。 default-src:指定加载内容的默认策略

We can in reusable middleware CSP construct and add header. Here is an example to let you get started. You may need to expand it. First, create a class to hold source.

public class CspOptions
        public List<string> Defaults { get; set; } = new List<string>();
        public List<string> Scripts { get; set; } = new List<string>();
        public List<string> Styles { get; set; } = new List<string>();
        public List<string> Images { get; set; } = new List<string>();
        public List<string> Fonts { get; set; } = new List<string>();
        public List<string> Media { get; set; } = new List<string>();

Developing a middleware necessarily require a constructor, this for .net core is injected into the runtime environment.

public sealed class CspOptionsBuilder  
     private readonly CspOptions options = new CspOptions();  
     internal CspOptionsBuilder() { }  
     public CspDirectiveBuilder Defaults { get; set; } = new CspDirectiveBuilder();  
     public CspDirectiveBuilder Scripts { get; set; } = new CspDirectiveBuilder();  
     public CspDirectiveBuilder Styles { get; set; } = new CspDirectiveBuilder();  
     public CspDirectiveBuilder Images { get; set; } = new CspDirectiveBuilder();  
     public CspDirectiveBuilder Fonts { get; set; } = new CspDirectiveBuilder();  
     public CspDirectiveBuilder Media { get; set; } = new CspDirectiveBuilder();  
     internal CspOptions Build()  
         this.options.Defaults = this.Defaults.Sources;  
         this.options.Scripts = this.Scripts.Sources;  
         this.options.Styles = this.Styles.Sources;  
         this.options.Images = this.Images.Sources;  
         this.options.Fonts = this.Fonts.Sources;  
         this.options.Media = this.Media.Sources;  
         return this.options;  
 public sealed class CspDirectiveBuilder  
     internal CspDirectiveBuilder() { }  
     internal List<string> Sources { get; set; } = new List<string>();  
     public CspDirectiveBuilder AllowSelf() => Allow("'self'");  
     public CspDirectiveBuilder AllowNone() => Allow("none");  
     public CspDirectiveBuilder AllowAny() => Allow("*");  
     public CspDirectiveBuilder Allow(string source)  
         return this;  

Well, we created a middleware.

namespace XSSDefenses.XSSDefenses.MiddlerWare
    public sealed class CspOptionMiddlerWare
        private const string HEADER = "Content-Security-Policy";
        private readonly RequestDelegate next;
        private readonly CspOptions options;

        public CspOptionMiddlerWare(
            RequestDelegate next, CspOptions options)
   = next;
            this.options = options;

        public async Task Invoke(HttpContext context)
            context.Response.Headers.Add(HEADER, GetHeaderValue());

        private string GetHeaderValue()
            var value = "";
            value += GetDirective("default-src", this.options.Defaults);
            value += GetDirective("script-src", this.options.Scripts);
            value += GetDirective("style-src", this.options.Styles);
            value += GetDirective("img-src", this.options.Images);
            value += GetDirective("font-src", this.options.Fonts);
            value += GetDirective("media-src", this.options.Media);
            return value;
        private string GetDirective(string directive, List<string> sources)
            => sources.Count > 0 ? $"{directive} {string.Join(" ", sources)}; " : "";

And set up its extension methods.

namespace XSSDefenses.XSSDefenses.Extensions
    public static class CspMiddlewareExtensions
        public static IApplicationBuilder UseCsp(
             this IApplicationBuilder app, Action builder)
            var newBuilder = new CspOptionsBuilder();

            var options = newBuilder.Build();
            return app.UseMiddleware(options);

We can now configure the middleware in the Startup category.

app.UseCsp(builder =>

Start the discovery, observation network resources. Browsers already allow local and remote resources.

Github address

Leave a Reply