Categories
Uncategorized

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) =>
            {
                ctx.Response.Headers.Add("Content-Security-Policy",
                            "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.

source:

*

: 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: //*.foo.com

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.

instruction:

script-src:定义有效的JavaScript源
style-src:定义样式表的有效来源
img-src:定义有效的图像源
connect-src:定义可以进行AJAX调用的有效源
font-src:定义有效的字体来源
object-src:定义<object>,元素的有效源
media-src:定义有效的音频和视频源
form-action:定义可用作HTML 
操作的有效源。 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)  
     {  
         this.Sources.Add(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)
        {
            this.next = next;
            this.options = options;
        }

        public async Task Invoke(HttpContext context)
        {
            context.Response.Headers.Add(HEADER, GetHeaderValue());
            await this.next(context);
        }

        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();
            builder(newBuilder);

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

We can now configure the middleware in the Startup category.

app.UseCsp(builder =>
            {
                builder.Styles.AllowSelf()
                .Allow(@"https://ajax.aspnetcdn.com/");
            });

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

Github address https://github.com/zaranetCore/-.NET-Core-And-XSSDefensesSolucation

Leave a Reply