CSP:如何允许不安全的-EVAL对于一个给定的URI前缀(火狐)(CSP: How to allo

2019-07-29 19:38发布

我试图使用MathJax作为使用相当严格的我们的web应用程序的一部分内容安全策略(CSP) 。 的问题是,MathJax是编码使用eval() [准确的说,在形式Function() ],它不被认为是由CSP默认安全。

我使用下面的CSP头目前:

X-Content-Security-Policy: allow 'self'; img-src *; media-src *; frame-src *; font-src *; frame-ancestors 'none'; style-src *; report-uri '/:save-csp-violation';

这将导致MathJax 2.0代码失败,因为它使用的Function() 我试图让不安全-EVAL(即Function()仅适用于位于下方的路径相同的起源内MathJax /:static/math/ 。 要做到这一点,我试图添加

unsafe-eval '/:static/math/*'

使全头的样子

X-Content-Security-Policy: allow 'self'; img-src *; media-src *; frame-src *; font-src *; frame-ancestors 'none'; style-src *; report-uri '/:save-csp-violation'; unsafe-eval '/:static/math/*'

但我仍然无法火狐13.0运行代码。 我收到一条错误消息,Firefox的Web控制台(位于工具 - Web开发):

[10:09:59.072] call to Function() blocked by CSP @ http://localhost:8080/:static/math/2.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML:29

但是,我没有得到的“报告-URI”一个CSP报告。 (正如你看到的,我目前正在运行的不通过SSL自定义本地主机端口的测试,如果有差别。之前结肠static是不是一个错字,我保留开始在内部使用的全部结肠路部分该应用程序中,所有用户的内容可以自由地定义其它网址。)

是我使用unsafe-eval属性不正确或者是不可能允许不安全-EVAL只为“自我”的子集? 这样做的目的是为了让不安全-EVAL只对同一产地路径前缀/:static/math ,严格的CSP JS代码执行的“ self ”和任何其他方法没有JS代码。

Answer 1:

有很多种问题:

  1. Content-Security-Policy (CSP)头不以这种方式工作。 CSP仅具有单个主机+端口组合(原点)的粒度。 如果你不能让所有的脚本有unsafe-eval ,没有脚本可以拥有它。 唯一可能的解决方法是不使用需要脚本unsafe-eval (幸运的是,MathJax不再需要unsafe-eval因为MathJax错误256是固定的)。

  2. allow的语法是一个古老的Mozilla的变异,不应该被使用。 目前的语法就是default-src ,随后被允许作为一切的根源,然后覆盖每个子类型(例如默认值方案,主机名或起源script-src如果需要)。 一些消息来源可以支持除了额外的源关键字self 。 例如, script-src支持unsafe-eval这意味着以其它方式允许执行任何脚本允许运行的eval()或功能()和unsafe-inline意味着任何一块标记的,可以支持某种内嵌脚本允许执行。 允许unsafe-eval是可以接受的,但unsafe-inline是几乎不走以剧本SRC(否则,你不应该用CSP打扰的话)。

  3. 正确的语法script-src如下:

     script-src 'self' cdnjs.cloudflare.com 

    结合装载MathJax从https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js

  4. MathJax还采用了内嵌式的属性,以便下面需要(除非已经允许)或MathJax将提高Exception ,而试图使数学:

     style-src 'self' 'unsafe-inline' 

    这是不可能的使用CSP,让JS插入样式属性,而不是有样式属性已插入HTML源代码有效果。

  5. 看来,火狐13.0(至少)不会立即“给家里打电话”确实在CSP违反的情况。 大部分违规报告确实会在活动结束后提出了一些时间。 Chrome浏览器似乎很有用提交报告,这将使它更容易一点,以测试更具侵略性。 从我的经验,Firefox不总是发送CSP报告在所有 - 可以使用某种启发式的不发送重复的消息。

最终,使MathJax工作,内容安全保护,则需要以下的头文件(假设你通过CDNJS使用MathJax):

Content-Security-Policy: default-src 'self'; script-src 'self' cdnjs.cloudflare.com; style-src 'self' 'unsafe-inline';

旧的浏览器(如火狐13),用于需要额外的参数,如options或使用非标准headere名称,如需要X-Content-Security-PolicyX-WebKit-CSP 。 这些黑客不再需要,因为用户代理支持标准的头现在。 ( 随着MSIE在违背MS边缘除外。)



文章来源: CSP: How to allow unsafe-eval for a given URI prefix (Firefox)