我将React应用程序与Webpack捆绑在一起,并添加了Content Security Policy (CSP)标头(特别是不允许在unsafe-eval
中使用script-src
)。当然,我要确保我的最终捆绑包和块中不包含eval()
。但是,最新的Firefox-dev 63.0b10仍然拒绝加载主块,并出现以下错误:
内容安全政策:该页面的设置禁止加载 自身资源(“ script-src”)。来源:调用eval()或相关 功能被CSP阻止。
好吧,但我的捆绑包中没有eval()
。
这些“相关功能”可能是什么?
P.S。这是self-answered question,但随时可以扩展
答案 0 :(得分:1)
Mozilla docs on CSP,列出“ eval()
和类似方法”作为可能的犯罪者:
[...]'不安全评估' 允许使用eval()和类似方法从字符串创建代码。 [...]
CSP3 specification § 1.2.1,提到“ eval()
和类似结构”:
通过给开发人员降低内容注入攻击的风险 对动态代码执行的相当精细的控制(通过eval()和类似的构造)[...]
但是最终的答案在CSP3规范的§ 6.1.10.4中有进一步的说明:
以下JavaScript执行接收器位于 “不安全评估”源表达式: eval() 功能() setTimeout()具有不可调用的初始参数。 setInterval()具有不可调用的初始参数。 注意:如果用户代理实施了非标准接收器,例如 setImmediate()或execScript(),它们也应该在 “不安全评估”。
因此,出于CSP的目的,“动态代码执行构造”,eval()
的“类似方法”,“相关功能”,“类似构造”的完整列表为:
eval()
Function() // typically new Function()
setTimeout() // with non-callable argument
setInterval() // with non-callable argument
setImmediate()
execScript()
以我为例,我在分发包中发现了几个new Function(...)
片段,现在想出如何防止它们出现的方式。
如果您使用grepl
或类似的类似grep
的工具来查找字符串匹配项,并以逐个字符的方式(而不是像常规的{{ 1}}),您可以使用以下命令在捆绑(最小化和代码分割)应用程序的所有文件中找到“动态代码执行结构”:
grep
或者,您可以关闭JS压缩程序(例如UglifyJS),然后使用普通的find "<build_dir>"" -type f -iname "*.js" -exec grepl -k 512 -H "(eval|Function)(\s|\t)*\(" '{}' \;
检查构建。