首页 > 其他分享 >identityserver4遇到的csp问题

identityserver4遇到的csp问题

时间:2022-12-01 17:46:03浏览次数:43  
标签:src 遇到 options CspDirectiveBuilder new csp com public identityserver4

问题:

部署identityserver4后,在view页面添加 行内css属性,或在view页面写js,运行时都会报错:

Refused to apply inline style because it violates the following Content Security Policy directive: "default-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-BQ5eA/mw6jES31KSfh/A55TC7nzftLBWpZBzzDfwUrA='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'style-src' was not explicitly set, so 'default-src' is used as a fallback.

经查找,原来是csp的原因

 

什么是CSP

CSP全称Content Security Policy ,可以直接翻译为内容安全策略,说白了,就是为了页面内容安全而制定的一系列防护策略. 通过CSP所约束的的规责指定可信的内容来源(这里的内容可以指脚本、图片、iframe、fton、style等等可能的远程的资源)。通过CSP协定,让WEB处于一个安全的运行环境中。

有什么用?

我们知道前端有个很著名的”同源策略”,简而言之,就是说一个页面的资源只能从与之同源的服务器获取,而不允许跨域获取.这样可以避免页面被注入恶意代码,影响安全.但是这个策略是个双刃剑,挡住恶意代码的同时也限制了前端的灵活性,那有没有一种方法既可以让我们可以跨域获取资源,又能防止恶意代码呢?

答案是当然有了,这就是csp,通过csp我们可以制定一系列的策略,从而只允许我们页面向我们允许的域名发起跨域请求,而不符合我们策略的恶意攻击则被挡在门外.从而实现

需要说明的一点是,目前主流的浏览器都已支持csp.所以我们可以放心大胆的用了.

 

指令说明

指令就是csp中用来定义策略的基本单位,我们可以使用单个或者多个指令来组合作用,功能防护我们的网站.

以下是常用的指令说明:

指令名

demo

说明

default-src

'self' cdn.example.com

默认策略,可以应用于js文件/图片/css/ajax请求等所有访问

script-src

'self' js.example.com

定义js文件的过滤策略

style-src

'self' css.example.com

定义css文件的过滤策略

img-src

'self' img.example.com

定义图片文件的过滤策略

connect-src

'self'

定义请求连接文件的过滤策略

font-src

font.example.com

定义字体文件的过滤策略

object-src

'self'

定义页面插件的过滤策略,如 <object>, <embed> 或者<applet>等元素

media-src

media.example.com

定义媒体的过滤策略,如 HTML6的 <audio>, <video>等元素

frame-src

'self'

定义加载子frmae的策略

sandbox

allow-forms allow-scripts

沙盒模式,会阻止页面弹窗/js执行等,你可以通过添加allow-forms allow-same-origin allow-scripts allow-popups, allow-modals, allow-orientation-lock, allow-pointer-lock, allow-presentation, allow-popups-to-escape-sandbox, and allow-top-navigation 策略来放开相应的操作

report-uri

/some-report-uri

 

指令值

所有以-src结尾的指令都可以用一下的值来定义过滤规则,多个规则之间可以用空格来隔开

demo

说明

*

img-src *

允许任意地址的url,但是不包括 blob: filesystem: schemes.

'none'

object-src 'none'

所有地址的咨询都不允许加载

'self'

script-src 'self'

同源策略,即允许同域名同端口下,同协议下的请求

data:

img-src 'self' data:

允许通过data来请求咨询 (比如用Base64 编码过的图片).

domain.example.com

img-src domain.example.com

允许特性的域名请求资源

*.example.com

img-src *.example.com

允许从 example.com下的任意子域名加载资源

https://cdn.com

img-src https://cdn.com

仅仅允许通过https协议来从指定域名下加载资源

https:

img-src https:

只允许通过https协议加载资源

'unsafe-inline'

script-src 'unsafe-inline'

允许行内代码执行

'unsafe-eval'

script-src 'unsafe-eval'

允许不安全的动态代码执行,比如 JavaScript的 eval()方法

 

 

怎么处理

1、在header加上指令

<meta http-equiv="X-Content-Security-Policy" content="style-src 'self' 'unsafe-inline';" />
<meta http-equiv="Content-Security-Policy" content="style-src 'self' 'unsafe-inline';" />

试了无效(求指导)

2、在webconfig上加指令

试了无效(求指导)

3、

我们可以在可重用的中间件中封装构建和添加CSP头。以下是一个让您入门的示例。你可以根据需要扩展它。首先,创建一个用于保存源的类。

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>();
    }
 

 开发一个中间件一定是需要一个构造器的,这将用于.net core 的注入到运行环境中。

 
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;  
     }  
 }  
 

 好了,我们创建一个中间件。

 
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)}; " : "";
    }
}
 

 以及设置它的扩展方法。

namespace XSSDefenses.XSSDefenses.Extensions
{
    public static class CspMiddlewareExtensions
    {
        public static IApplicationBuilder UseCsp(
             this IApplicationBuilder app, Action<CspOptionsBuilder> builder)
        {
            var newBuilder = new CspOptionsBuilder();
            builder(newBuilder);
 
            var options = newBuilder.Build();
            return app.UseMiddleware<CspOptionMiddlerWare>(options);
        }
    }
}

 

我们现在可以在Startup类中配置中间件。

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

 启动发现,观察网络资源。浏览器已经允许本地和远程资源

 

引用文章:

http://t.zoukankan.com/firstdream-p-8392564.html

https://www.cnblogs.com/ZaraNet/p/11458747.html

 

标签:src,遇到,options,CspDirectiveBuilder,new,csp,com,public,identityserver4
From: https://www.cnblogs.com/helloStone/p/16942139.html

相关文章