首页 > 解决方案 > 启用 CSP 时要避免哪些与 eval() 相关的函数?

问题描述

我将我的 React 应用程序与 Webpack 捆绑在一起,并添加内容安全策略 (CSP)标头(特别是不允许unsafe-evalin script-src)。当然,我确保我的最终包和块不包含eval(). 但是,最新的 Firefox-dev 63.0b10 仍然拒绝加载主块,并出现以下错误:

内容安全策略:页面的设置阻止了自身资源的加载(“script-src”)。来源:调用 eval() 或被 CSP 阻止的相关函数。

嗯,但我eval()的包里没有。那些“相关功能”可能是什么?

PS这是一个自我回答的问题,但随时扩展

标签: javascriptevalcontent-security-policy

解决方案


Mozilla docs on CSP将“eval()和类似方法”列为可能的违规者:

[...]'unsafe-eval' 允许使用eval()和类似的方法从字符串创建代码。[…]

CSP3 规范 § 1.2.1,提到“eval()和类似的结构”:

eval()通过让开发人员对 [...] 动态代码执行(通过和类似结构)[...]进行相当精细的控制,降低内容注入攻击的风险

但最终答案在 CSP3 规范中进一步说明,在§ 6.1.10.4 中:

以下 JavaScript 执行接收器在 " unsafe-eval" 源表达式上进行了控制:

  • eval()
  • Function()
  • setTimeout()带有不可调用的初始参数。
  • setInterval()带有不可调用的初始参数。

setImmediate()注意:如果一个用户代理实现了像or这样的非标准接收器 execScript(),它们也应该在 " unsafe-eval" 上进行门控。

因此,出于 CSP 的目的,“动态代码执行结构”、 eval()“类似方法”、“相关函数”、“类似结构”的完整列表是:

eval()
Function()     // typically new Function()
setTimeout()   // with non-callable argument
setInterval()  // with non-callable argument
setImmediate()
execScript()

就我而言,我new Function(...)在捆绑包中发现了一些碎片,现在正在弄清楚如何防止它们出现。

奖金

如果您使用grepl或类似grep的工具来查找字符串匹配项并逐个字符地打印周围的上下文(而不是像往常一样逐行grep),您可以使用以下命令来查找“动态代码执行结构”在捆绑(缩小和代码拆分)应用程序的所有文件中:

find "<build_dir>" -type f -iname "*.js" -exec grepl -k 512 -H "(eval|Function)(\s|\t)*\(" '{}' \;

或者,您可以关闭 JS minifier(例如 UglifyJS)并使用 normal 检查您的构建grep


推荐阅读