CSP:如何为给定的URI前缀(Firefox)提供不安全的评估 [英] CSP: How to allow unsafe-eval for a given URI prefix (Firefox)

查看:352
本文介绍了CSP:如何为给定的URI前缀(Firefox)提供不安全的评估的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用 MathJax 作为我们的Web应用程序的一部分,它使用了非常严格的内容安全策略(CSP)。问题是MathJax被编码为使用 eval() [的确切形式是 Function()] CSP默认不认为是安全的。



我现在使用以下CSP头文件:

<$ p $ X-Content-Security-Policy:allow'self'; img-src *; media-src *; frame-src *; font-src *;框架 - 祖先'没有'; style-src *; report-uri'/:save-csp-violation';

这导致MathJax 2.0代码失败,因为它使用 code>。我试图只对位于路径 /:static / math / 下的相同原点的MathJax允许unsafe-eval(也就是 code>。要做到这一点,我试图添加

pre $ unsafe -eval'/:static / math / *'
code>

使整个标题看起来像

  X-Content-Security-Policy:允许'自我'; img-src *; media-src *; frame-src *; font-src *;框架 - 祖先'没有'; style-src *; report-uri'/:save-csp-violation'; unsafe-eval'/:static / math / *'

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

]调用Function()被CSP阻止@ http:// localhost:8080 /:static / math / 2.0 / MathJax.js?config = TeX-AMS-MML_HTMLorMML:29

但是,我没有收到一份CSP报告给report-uri。 (正如你所看到的,我目前正在通过自定义本地主机端口来运行测试,而不使用SSL,以防万一。 static 之前的冒号不是拼写错误,所有的用户内容都可以自由的定义其他的URL。)

我使用 unsafe-eval 属性是不正确的还是不可能只允许unsafe-eval仅用于'self'的子集?目的是只允许不安全的eval为相同的原始路径前缀 /:static / math ,对于 self 执行严格的CSP JS代码,并且没有任何其他方法的JS代码。

解决方案

有很多问题:


  1. CSP头不以这种方式工作。 CSP仅具有单个主机+端口组合(来源)的粒度。如果您的主机中不允许任何脚本具有 unsafe-eval ,则脚本不能拥有它。唯一可行的解​​决方法是不要使用需要 unsafe-eval 的脚本(祝你自己写一个MathJax替代品)


  2. 允许语法是旧的Mozilla变体,不应使用。当前的语法是说 default-src ,然后是方案或主机名或源,它们被允许作为所有东西的源,然后覆盖每个子类型的默认值(例如 script-src )。除了 self 之外,一些源可能支持额外的源关键字。例如, script-src 支持 unsafe-eval ,这意味着任何允许执行的脚本都是允许的运行eval()或Function()和 unsafe-inline ,这意味着任何可以支持某种内联脚本的标记都可以执行。允许 unsafe-eval 可能是可以接受的,但是不安全的内联几乎与script-src没有关系(否则,你不应该打扰CSP)。

  3. 正确的语法为 script-src as如下所示:

    $ $ p code $ script $ s $ self $ unsafe-inline
    异常

      style-src'self''unsafe-inline'

    不能使用CSP来允许JS插入样式属性,也不能将HTML源代码中已经插入的样式属性有一个效果。

  4. 看来,Firefox 13.0(至少)不会立即回家在违反CSP的情况下。事件发生后的大部分违规报告都会提交。 Chrome似乎对提交报告更加积极,这将使测试更容易一些。根据我的经验,Firefox并不总是发送CSP报告 - 它可能使用某种启发式方式来发送重复的消息。


额外奖励:为了支持webkit,您必须使用 X-WebKit-CSP HTTP头重复配置。


$ b $最后,为了让MathJax能够使用Content-Security-Protection,你需要下面的头文件(假设你自己分发MathJax库,而不是通过MathJax CDN):

  X-Content-Security-Policy:default-src'self'; script-src'self''unsafe-eval'; style-src'self''unsafe-inline'; options eval-script 
X-WebKit-CSP:default-src'self'; script-src'self''unsafe-eval'; style-src'self''unsafe-inline'
Content-Security-Policy:default-src'self'; script-src'self''unsafe-eval';在这里选项 / code>属性是Firefox 13.0及更低版本所必需的。我在 https://github.com/mathjax/MathJax/issues/上向MathJax报告了CSP问题256


I'm trying to use MathJax as part of our web application which uses pretty strict Content Security Policy (CSP). The problem is that MathJax is coded to use eval() [to be exact, in form of Function()] which is not considered safe by default by CSP.

I'm using following CSP header currently:

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

Which causes MathJax 2.0 code to fail because it uses Function(). I tried to allow unsafe-eval (i.e. Function()) only for MathJax located within the same origin below path /:static/math/. To do that, I tried to add

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

to make the full header look like

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/*'

but I still cannot Firefox 13.0 to run the code. I'm getting an error message to Firefox Web Console (located in 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

However, I'm not getting a CSP report to the 'report-uri'. (As you see, I'm currently running the test through custom localhost port without SSL, in case that makes a difference. The colon before static is not a typo, I'm reserving all path parts starting with a colon for internal use of the application, all user content may freely define other URLs.)

Is my use of unsafe-eval attribute incorrect or is it impossible to allow unsafe-eval only for subset of 'self'? The intent is to allow unsafe-eval only for same origin path prefix /:static/math, strict CSP JS code execution for 'self' and no JS code for any other method.

解决方案

There're multiple issues:

  1. CSP headers do not work this way. CSP only has granularity of a single host+port combination (origin). If you cannot allow any script in your host to have unsafe-eval, no script can have it. The only possible workaround is to not use a script that requires unsafe-eval (good luck writing a MathJax replacement by yourself).

  2. The allow syntax is an old Mozilla variant and should not be used. The current syntax is to say default-src followed by scheme or host names or origins that are allowed as source of everything and then override the default value for each sub type (e.g. script-src) as needed. Some sources may support additional source keywords in addition to self. For example, the script-src supports unsafe-eval which means that any script that is otherwise allowed to execute is allowed to run eval() or Function(), and unsafe-inline meaning that any piece of markup that can support some kind of inline script is allowed to execute. Allowing unsafe-eval may be acceptable but unsafe-inline is pretty much no-go with script-src (otherwise, you should not bother with the CSP at all).

  3. The correct syntax for script-src as follows:

    script-src 'self' 'unsafe-inline'
    

  4. MathJax also uses inline style attributes so following is needed (unless already allowed) or MathJax will hit Exceptions while trying to render the math:

    style-src 'self' 'unsafe-inline'
    

    It is not possible to use CSP to allow JS to insert style attributes and not have style attributes already inserted in the HTML source to have an effect.

  5. It seems that Firefox 13.0 (at least) does not immediately "call home" in case of CSP violation. Most of the violation reports do get submitted some time after the event. Chrome seems to be much more aggressive with the report submission which will make it a bit easier to test against. From my experience, Firefox does not always send CSP report at all - it may be using some kind of heuristic to not send repeated messages.

Bonus: To support webkit, you have to repeat the config with X-WebKit-CSP HTTP header.

In the end, to make MathJax work with Content-Security-Protection, you need following headers (assuming you're distributing MathJax library by yourself, instead of via the MathJax CDN):

X-Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; options eval-script
X-WebKit-CSP: default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'

Here the options attribute is required for Firefox 13.0 and lesser. I have reported the CSP issue to MathJax at https://github.com/mathjax/MathJax/issues/256.

这篇关于CSP:如何为给定的URI前缀(Firefox)提供不安全的评估的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆