启用 CSP 时要避免哪些与 eval() 相关的函数?

Iva*_*rop 5 javascript eval content-security-policy

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

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

好吧,但eval()我的捆绑包中没有。那些“相关功能”可能是什么?

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

Iva*_*rop 5

CSP 上的 Mozilla 文档将“eval()和类似方法”列为可能的罪犯:

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

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

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

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

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

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

注意:如果用户代理实现了非标准的接收器,如 setImmediate()execScript(),它们也应该在“ unsafe-eval”上被门控。

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

eval()
Function()     // typically new Function()
setTimeout()   // with non-callable argument
setInterval()  // with non-callable argument
setImmediate()
execScript()
Run Code Online (Sandbox Code Playgroud)

就我而言,我new Function(...)在包中发现了一些片段,现在正在研究如何防止它们出现。

奖金

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

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

或者,您可以关闭 JS minifier(例如 UglifyJS)并使用正常的grep.