CSP:如何允许给定URI前缀的不安全eval(Firefox)

Mik*_*nen 14 javascript security firefox mathjax content-security-policy

我正在尝试使用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';
Run Code Online (Sandbox Code Playgroud)

这导致MathJax 2.0代码失败,因为它使用Function().我试图Function()仅允许位于路径下相同原点的MathJax的unsafe-eval(ie )/:static/math/.为此,我尝试添加

unsafe-eval '/:static/math/*'
Run Code Online (Sandbox Code Playgroud)

使完整的标题看起来像

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/*'
Run Code Online (Sandbox Code Playgroud)

但我仍然无法使用Firefox 13.0来运行代码.我收到Firefox Web Console(位于Tools - Web Developer)的错误消息:

[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
Run Code Online (Sandbox Code Playgroud)

但是,我没有收到"报告 - uri"的CSP报告.(如你所见,我目前正在通过自定义localhost端口运行测试而不使用SSL,以防有所不同.之前的冒号static不是拼写错误,我保留所有以冒号开头的路径部分供内部使用应用程序,所有用户内容可以自由定义其他URL.)

我对unsafe-eval属性的使用是否不正确或是否仅允许'self'的子集不安全eval?目的是允许unsafe-eval仅用于相同的原始路径前缀/:static/math,严格的CSP JS代码执行' self'和任何其他方法的JS代码.

Mik*_*nen 18

存在多个问题:

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

  2. allow语法是一个古老的Mozilla的变异,不应该被使用.当前语法default-src后面是允许作为所有内容源的方案或主机名或来源,然后script-src根据需要覆盖每个子类型(例如)的默认值.除了之外,一些来源可能还支持其他源关键字self.例如,script-src支持unsafe-eval意味着允许执行任何其他允许执行的脚本运行eval()或Function(),并且unsafe-inline意味着允许执行任何支持某种内联脚本的标记.允许unsafe-eval可能是可以接受的,但unsafe-inline与script-src几乎没有关系(否则,你根本不应该打扰CSP).

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

    script-src 'self' cdnjs.cloudflare.com
    
    Run Code Online (Sandbox Code Playgroud)

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

  4. MathJax还使用内联样式属性,因此需要跟随(除非已经允许)或MathJax将Exception在尝试渲染数学时引发:

    style-src 'self' 'unsafe-inline'
    
    Run Code Online (Sandbox Code Playgroud)

    无法使用CSP来允许JS插入样式属性,并且不会在HTML源中插入样式属性以产生效果.

  5. 似乎Firefox 13.0(至少)在CSP违规的情况下不会立即"回家".大多数违规报告都会在活动结束后的某个时间提交.报告提交时,Chrome似乎更具侵略性,这将使测试更容易一些.根据我的经验,Firefox并不总是发送CSP报告 - 它可能使用某种启发式方法来发送重复的消息.

最后,要使MathJax与Content-Security-Protection一起使用,您需要以下标题(假设您通过CDNJS使用MathJax):

Content-Security-Policy: default-src 'self'; script-src 'self' cdnjs.cloudflare.com; style-src 'self' 'unsafe-inline';
Run Code Online (Sandbox Code Playgroud)

较旧的浏览器(例如Firefox 13)过去需要额外的参数,例如options或要求使用非标准的headere名称,如X-Content-Security-PolicyX-WebKit-CSP.由于用户代理现在支持标准标题,因此不再需要这些黑客攻击.(与MS Edge相反,MS Edge除外.)