在electron开发中免不了要和CSP打交道,从2.0版本开始,如果使用electron 的开发人员没有定义Content-Security-Policy, Electron就会在DevTool console发出警告提示,下面简单来认识下
内容安全策略(CSP)
内容安全策略(CSP:Content-security-Poligy)是一个颜外的安全层,用于检测并削弱某些特定类型的攻击,包括跨站脚本(XSS) 和数据注入攻击等。核心思想:网站通过发送一个CSP 头部,来告诉浏览器什么是被授权执行的与什么是需要被禁止的,被誉为专门为解决XSS攻击而生的神器。
1 简介:
XSS攻击利用了浏览器对于从服务器所获取的内容的信任。恶意脚本在受害者的浏览器中得以运行,因为浏览器信任其内容来源,即使有的时候这些脚本并非来自于它本该来的地方。
CSP通过指定有效域—即浏览器认可的可执行脚本的有效来源一使服务器管理者有能力减少或消除XSS攻击所依赖的载体。.
一个CSP兼容的浏览器将会仅执行从白名单域获取到的脚本文件,忽略所有的其他脚本(包括内联脚本和HTML的事件处理属性)。
2 CSP的分类:
(1) Content-Security-Policy
配置好并启用后,不符合CSP 的外部资源就会被阻止加载。
(2) Content-Security-Policy-Report-Only
表示不执行限制选项,只是记录违反限制的行为。它必须与report-uri选项配合使用。
3 CSP的使用:
(1) 在HTTP Header上使用(首选)
可以在网关的Filter中配置或者在Nginx服务器配置
"Content-Security-Policy:" 策略
"Content-Security-Policy-Report-Only: "策略
(2) 在HTML上使用
<meta http-equiv="content-security-policy" content="策略">
<meta http-equiv="content-security-policy-report-only" content="策略">
如果Content-Security-Policy-Report-Only头部和 Content-Security-Policy同时出现在一个响应中,两个策略均有效。在Content-Security-Policy 头部中指定的策略有强制性,而Content-Security-Policy-Report-Only中的策略仅产生报告而不具有强制性,支持CSP的浏览器将始终对于每个企图违反你所建立的策略都发送违规报告,如果策略里包含一个有效的report-uri 指令。
4 使用案例:
开启CSP方法:
<!--设置 HTTP 的头部字段-->
response.setHeader("Content-Security-Policy","default-src http: https:");
<!--设置网页的<meta>标签-->
<meta http-equiv="Content-Security-Policy" content="form-action 'self';">
限制所有的外部资源,都只能从当前域名加载,不包含子域名
Content-Security-Policy: default-src 'self'
限制所有的外部资源,都只能从当前域名及其子域名加载
Content-Security-Policy: default-src 'self' *.youkuaiyun.com
图片可以从任何地方加载(注意"*"通配符)。
多媒体文件仅允许从 media1.com 和 media2.com 加载(不允许从这些站点的子域名)。
可运行脚本仅允许来自于scripts.youkuaiyun.com。
Content-Security-policy: default-src 'self'; img-src *; media-src medial.com media2.com; script-src scripts.youkuaiyun.com
服务器仅允许通过HTTPS方式并仅从onlinebanking.abc.com域名来访问文档(线上银行网站)
Content-Security-Policy: default-src https://onlinebanking.abc.com
5 启用违例报告:
默认情况下,违规报告并不会发送。为启用发送违规报告,你需要指定 report-uri策略指令,并提供至少一个UR!地址去递交报告:
Content-Security-Policy: default-src https://onlinebanking.abc.com
然后你需要设置你的服务器能够接收报告,使其能够以你认为恰当的方式存储并处理这些报告。
6 违例报告样本:
我们假设页面位于 http://example.com/signup.html。它使用如下策略,该策略禁止任何资源的加载,除了来自cdn.example.com的样式表。
Content-Security-Policy: default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports
signup.html 的HTML像这样:
<!DOCTYPE html>
<html>
<head>
<title>Sign Up</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
...Content...
</body>
</html>
能看出其中的错误吗? css仅允许加载自cdn.example.com,然而该页面企图从自己的源
(http://example.com)加载。当该文档被访问时,一个兼容CSP的浏览器将以POST请求的形式发送违规报告到 http://example.com/_/csp-reports,内容如下:
{
"csp-report": {
"document-uri": "http://example.com/signup.html",//访问的网络资源
"referrer": "",
"blocked-uri": "http://example.com/css/style.css",//违规资源的路径
"violated-directive": "style-src cdn.example.com",
"original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports"
}
}
blocked-uri字段中包含了违规资源的完整路径
7 兼容性:
8 配置解释:
如果只是为了在开发阶段进行测试,您可以临时禁用 CSP。注意,这不是一个安全的长期解决方案,不能在生产环境中使用。您可以在创建 BrowserWindow 时禁用安全策略:
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
webSecurity: false, // 禁用 CSP 和其他安全策略
},
});
但是这样做了以后,electron会在浏览器报警告,许多情况下也不会起作用,electron会报错,还是要配置。
default-src 指令:default-src指令定义了获取诸如JavaScript、图片、CSS、字体、AJAX请求、框架、HTML5媒体等资源的默认策略。并不是所有的指令都回退到default-src。
script-src指令:定义有效的JavaScript源。
style-src指令:定义样式表或CSS的有效源。
img-src指令:定义有效的图像源。
connect-src指令:适用于XMLHttpRequest (AJAX), WebSocket, fetch(), <a ping>或EventSource。如果不允许,浏览器会模拟一个400 HTTP状态码。
font-src指令:定义字体资源的有效来源(通过@font-face加载)。
object-src指令:定义有效的插件源,如<object>、<embed>或<applet>。
media-src指令:定义有效的音频和视频源,例如HTML5 <audio>, <video>元素。
frame-src指令:定义加载帧的有效源。在CSP Level 2中,frame-src被弃用,取而代之的是child-src指令。CSP Level 3有未弃用的frame-src,如果不存在,它将继续遵从child-src。
sandbox指令:为请求的资源启用沙盒,类似于iframe沙盒属性。沙盒应用同源策略,防止弹出窗口,插件和脚本执行被阻止。您可以将沙盒值保留为空以保留所有限制, 或者添加以下标志:allow-forms allow-same-origin allow-scripts allow-popups, allow-modals, allow-orientation-lock, allow-pointer-lock, allow-presentation, allow-popup -to-escape-sandbox和allow-top-navigation
report-uri指令:指示浏览器将策略失败的报告发送到此URI。还可以使用Content-Security-Policy-Report-Only作为HTTP头名称,指示浏览器只发送报告(不阻止任何内容)。 该指令在CSP Level 3中已被弃用,取而代之的是报告指令。
child-src指令:为使用<frame>和<iframe>等元素加载的web工作者和嵌套浏览上下文定义有效的源。
form-action指令:定义可用作HTML <form>动作的有效源。
frame-ancestors指令:使用<frame> <iframe> <object> <embed> <applet>定义嵌入资源的有效源。将此指令设置为“none”应该大致相当于X-Frame-Options: DENY
plugin-types指令:为通过<object>和<embed>调用的插件定义有效的MIME类型。要加载<applet>,必须指定application/x-java-applet。
base-uri指令:定义一组允许的url,这些url可以在HTML基标记的src属性中使用。
report-to指令:定义由Report-To HTTP响应头定义的报告组名称。
worker-src指令:限制可以作为Worker、SharedWorker或ServiceWorker加载的url。
manifest-src指令:限制可以加载应用程序清单的url。
prefetch-src指令:定义请求预取和预呈现的有效来源,例如通过带有rel="prefetch"或rel="prerender"的link标签:
navigate-to指令:限制文档可以通过任何方式导航到的url。例如,当单击链接时,提交表单或窗口。调用Location。如果存在form-action,则在提交表单时忽略该指令。
upgrade-insecure-requests指令:自动转换url从http到https的链接,图像,javascript, css等。
block-all-mixed-content指令:阻止对非安全http url的请求。
比如script-src可以有这些项可以指定:
<chost-source> 是指来自于哪一个主机,也就是域名
<scheme-source> 是指协议,如http、https、ws、wss、file、base64、blob、data等
'self'是指同一个域下
'unsafe-inline'是指直接插入在页面中的内容
'unsafe-eval'是否允许调用eval函数
'none'不信任任何内容
'nonce-<base64-value>'
如果你担心内联脚本的JS注入,但是又需要内联JS的执行。可以使用nonce属性。CSP Header会返回一个随机字符串,当它与script标签的nonce属性相匹配时,说明这段内联的js是安全的,是可以执行的
<hash-source>和'nonce-<base64-value>'类似
'strict-dynamic'是指当我们信任这个脚本之后,后续它又引入了一个脚本,是否信任这个后续引入的脚本
关于CSP的更多信息:https://content-security-policy.com/