Content Security Policy的想法是告诉网络浏览器要从何处加载哪些内容。这意味着,例如,如果未明确允许'unsafe-inline'
(这不是最好的做法),攻击者将无法注入自己的代码。
Google还发布了CSP Evaluator,旨在发现您的政策中可能存在的错误。使用默认设置,该工具建议对'strict-dynamic'
使用'script-src'
策略。其背后的想法是,您为所需的任何JavaScript源编写一个加载器,并禁止其他所有内容。
什么是实现这种加载程序的“正确”方法?应该使用自己编写加载程序(例如,参见下文)还是应该使用工具来创建这样的加载程序? (请注意,此问题并非要求提供具体的工具建议)
var imported = document.createElement('script');
imported.src = '/path/to/imported/script';
document.head.appendChild(imported);
我的网站目前具有以下政策:
default-src 'none';
img-src 'self';
style-src 'self' https://stackpath.bootstrapcdn.com 'sha256-bviLPwiqrYk7TOtr5i2eb7I5exfGcGEvVuxmITyg//c=';
script-src https://use.fontawesome.com https://code.jquery.com https://cdnjs.cloudflare.com https://stackpath.bootstrapcdn.com;
base-uri 'none';
form-action 'none';
frame-ancestors 'none';
Google的工具建议如下:
主机白名单可以经常被绕开。考虑将
'strict-dynamic'
与CSP随机数或哈希值结合使用。
这样,我想实现一个加载器来加载这些JS框架,并且我想知道如何最好地解决这个问题。
答案 0 :(得分:2)
一个直接的答案是,只要您正在动态加载的脚本(/path/to/imported/script
)托管在您已经在script-src
中列入白名单的域中,就无需修改您的CSP或更改加载程序-一切都会按预期进行。
但是,更广泛的问题是您的script-src
白名单中包含托管Javascript的域,攻击者可以在应用程序中发现标记注入错误以绕过CSP来使用这些域。例如,https://cdnjs.cloudflare.com
托管了Angular(https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.2/angular.min.js
),攻击者可以使用Angular将HTML注入转换为任意脚本执行(here是有关此问题的论文)。
CSP评估程序工具中的建议是将您的应用程序切换为依赖于script-src
,该{@ 1}使用CSP随机数而不是白名单。为此,您需要遵循https://csp.withgoogle.com/docs/strict-csp.html中概述的过程-基本上,请确保每个<script>
元素都具有正确的nonce
属性,该属性随每次页面加载而变化,或者使用CSP3 hashes用于静态脚本。
您的CSP如下所示:
... script-src 'nonce-[random-value]' 'strict-dynamic' 'unsafe-inline' https:; ...
如果您使用'strict-dynamic'
,则不必更改脚本加载器,因为浏览器将自动信任通过编程API(例如appendChild()
)添加到页面的脚本。