<p>MathJax 需要不安全的“内容安全策略”</p>

创建于 2012-06-11  ·  42评论  ·  资料来源: mathjax/MathJax

当前的 MathJax 实现使用以下在现代世界中被认为不安全且不能与默认 Content-Security-Policy (http://www.w3.org/TR/CSP/) 标头一起使用的功能:

  • 字符串的 JavaScript 求值(带有字符串的 new Function() 或 eval())(1)
  • 通过 JavaScript 插入的内联样式属性 (2)

是否应该修复问题 (2) 但至少应该修复 (1) 是有争议的,因为 Content-Security-Policy 没有足够的粒度来允许 MathJax 作为受信任的脚本执行并且同时不解释所有其他 JavaScript文件特别受信任。 目前,如果想使用 MathJax,他必须在任何地方都允许 eval()。 问题 (1) 还会导致错误 #130(MathJax 与 ECMAScript 5 严格模式不兼容)。

目前,使 MathJax 工作的唯一方法,即使使用本地安装的 MathJax 代码,也是使用以下 CSP HTTP 标头(Firefox 13.0 及更低版本包含已弃用的“选项”标头):

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'

如果 MathJax 是从与页面内容相同的来源分发的,这些标头将允许某些 CSP 提供的保护并且仍然允许 MathJax 工作。

Accepted Fixed Test Not Needed v2.4

最有用的评论

@kaushalmodi ,请参阅我上面关于如何避免该问题的评论,或我对您链接到的问题的评论。 如果您使用限制脚本执行的 CSP,则必须更改配置 MathJax 的方式。

所有42条评论

不安全的评估对我来说也是一个大问题。 很快,chrome 将强制所有扩展程序采用禁止使用eval内容安全策略。 我们目前正在尝试升级Readium以符合此要求,但我们不能这样做并使用 MathJax

+1

多谢你们。 我们会调查的。

只是初步更新。 似乎可以尽快解决一些问题(希望对于 Chrome 商店来说足够了)。 但是,我们不确定性能会受到怎样的影响——正如您可以猜到的那样,这可能很糟糕。 当@dpvc可以更详细地查看此内容并可能创建一些实验性分支时,我们会及时通知您。

如果您对特定代码有其他意见、问题和建议,请告诉我们。

我自己花了一些时间研究它。 看来你们需要停止过早的优化。 评估字符串并不比创建闭包快。

此外,您不应该在每个加载 Mathjax 的页面上运行eval()来检查您是否可以运行eval() 。 基本上,需要去。

new Function()调用不是为了速度,而是为了内存。 new Function()不会创建闭包,因此不会保留本地范围。 由于这是面向对象编程模型的核心,并且有很多对象在使用,它可能会对内存使用产生影响。 我没有在最近的浏览器中对此进行任何测试。

至于eval的使用,MathJax 确实使用它来处理它的内联配置块,并且此时无法轻易替换。 因此,MathJax 的“安全”版本需要使用外部配置文件(这应该不是问题,而且可能更符合安全策略)。 您提到的eval调用不是确定eval是否可以运行,而是确定它是否在全局命名空间中运行(并非所有浏览器都如此)。 我知道这需要删除才能满足您的安全需求。

不是闭包在 javascript 中的工作方式。 您不会抓住本地范围内的所有内容; 你只捕获你的函数使用的东西。 您的CONSTRUCTOR函数不使用本地范围内的任何内容,因此创建闭包是免费的。 这是对从未存在的问题的过早优化。

eval而言,我的观点是,如果不需要,您不应该在页面上运行代码,特别是如果该代码使用不安全的eval() 。 如果 Mathjax 已包含在内联配置中,则仅使用该EVAL函数,因此,在需要之前不要对其运行测试。 但实际上,为什么配置必须是可执行代码。 它实际上只是传递给函数的一段 JSON。 为什么不直接传递 JSON,解析它并让 MathJAX 调用该函数?

不是闭包在 javascript 中的工作方式。 您不会抓住本地范围内的所有内容; 你只捕获你的函数使用的东西。

我认为事情没有那么明确。 首先,在 2008 年编写这部分代码时,情况并非如此。 我今天早上刚刚进行了测试,似乎确认当时运行​​的 Safari、Firefox、Opera 和 IE 版本都按照我描述的方式工作(完整的作用域链保留在闭包中,无论使用的变量如何)。 我参考的网站今天早上似乎关闭了(昨天就上线了),所以我无法查看详细信息,但我记得这是 ECMAScript 262 规范的一部分。

当前版本的 Safari、Chrome、Firefox 和 IE 似乎确实如您所描述的那样工作,所以从那以后情况发生了变化。 看起来 Safari 4、Firefox 3.6 和 IE9 是发生变化的地方; 我没有旧版本的 Chrome 来测试,所以不知道那里的历史。 IE8 具有较旧的行为,而 Opera 12 仍然如此。 我没有检查移动设备。 其中一些浏览器在 MathJax 的支持列表中,因此对于 MathJax 来说,这仍然是我们必须考虑的一个问题。 当然,我确信可以根据您的需要解决一些问题。

至于 JSON 数据,配置块可能不仅仅是一个MathJax.Hub.Config()调用。 例如,您可以安装事件侦听器,或向 TeX 输入 jax 添加函数以实现附加命令,等等。 这些不能成为 JSON 数据的一部分,因为它们包含可执行代码。 这个特性并不总是被使用,但它确实_is_被实际的网站使用。 此外,并非所有目标浏览器都内置了 JSON 库,因此需要额外的库来进行解析。 (当然不是不可逾越的,但要下载更多代码。)

+1 更改此设置,以便(除其他外)Github 将允许 MathJax 再次出现在他们的 wiki 中。

@ketch你有关于 Github 在这方面发表声明的参考吗? 我看不出这个问题如何影响 Github Wiki 安全性。

@pkra我不确定这是原因,但我相信是这样。 我被这个页面上的评论引导到这个:

http://stackoverflow.com/questions/16889421/how-to-insert-javascript-to-enable-mathjax-on-github-wiki-pages

看看

https://github.com/blog/1477-content-security-policy

我相信 MathJax 支持在他们实现 CSP 功能的同时消失了。

谢谢,这很有趣。 我不确定这两者是否相关,但谁知道——github 团队从未公开讨论过为什么他们删除了 MathJax。 如果他们的设置实际上不是问题的事情是原因,那将是不幸的。

+1 符合 CSP。

+1

我读了这个帖子,发现它非常有用,而且相当公正。 我将提出我的主张,即他们 [github] 会在安全问题上阻止 exec、CSP 之类的事情,并且不允许这样做。

除了被该代码示例和您对过去版本的神话般的计算机知识所迷惑之外,我发现它仍然非常有趣,并且认为应该提供一个功能以供其继续使用,尽管它不应该干扰快乐在安全相关的世界中使用 MathJAX 的路径。

顺便说一句,我通过电子邮件向 Github 支持人员发送了关于他们放弃 MathJax 的原因。 这是回复:

CSP 是原因之一。 其他原因包括性能问题和硬维护。 如果我们消除了导致我们删除它的原因,我们可能会考虑重新添加它,但我不能保证。

谢谢@ketch ,很高兴知道。

@dpvc我们应该将其添加到下一个里程碑吗?

:+1:

@pkra ,我打算添加它。 只是在列表中的数字还没有下降这么多。

@dpvc对。 我主要想知道解决这个问题是否需要进行重大更改(尤其是内联配置),即强制版本跳转。

我们为允许通过 MathJax 变量进行配置所做的更改应该可以在不跳转的情况下包含它。 我很确定我可以通过向后兼容性来做到这一点,而不必制作单独的“安全”版本的 MathJax.js。 当然,在开发过程中可能会出现一些事情,这会使工作中的活动变得混乱。 它还没有被编写或测试。

+1 使 MathJax 安全。 由于安全问题,无法在生产中使用这个不错的库,太糟糕了。

在这个问题上有什么进展吗? 我正在尝试以编程方式将 MathJax 注入带有 Chrome 扩展程序的页面,如果不是一堵砖墙,我至少是一堵相当坚固的墙。 如 emichael/texthings#4 中所述,我现在最大的问题是MathJax.js:265 。 我能够消除对

new Function()

如上所述,通过将它们转换为闭包非常容易,但我不知道如何使用eval或内联脚本来解决问题。

编辑:我最终为用户提供了将 unsafe-eval 和 unsafe-inline 添加到 CSP 的选项,但是将 MathJax 变为安全 CSP 的长期修复会很好。 :+1:

@emichael ,我们计划在下一个版本中包含更改(计划在下个月发布),但我还没有完成。 一个原因是我还没有研究你如何实际测试它(如何设置需要它的环境)。 如果你能给我一个关于在哪里看或最小的测试环境可能是什么的建议,那会有所帮助。

另外,关于 eval 的错误是在运行时还是在编译时发生的? 也就是说,如果 MathJax.js 仅包含一个 eval 调用,即使它从未使用过,它是否会发生,或者它是否仅在实际尝试 eval 时发生? 我对规范的阅读表明它应该是一个运行时错误,这对我来说会更好,但我想你可能知道答案。

如果你有一个测试服务器,你可以在响应头中设置 Content-Security-Policy。 只要确保script-src不包括'unsafe-eval''unsafe-inline' (GitHub 本身就是一个很好的例子)。 如果你不这样做,你可以使用一个非常小的 Chrome 扩展来自己注入标头。

这是一个运行时错误。

谢谢。 我会看看我能做什么。

eval 命令仅用于处理内联配置块(并且有一个初始命令来测试在这种情况下如何处理全局变量)。 最初的配置可以推迟到使用内联配置,如果您避免使用内联配置,那么应该处理它。 在 v2.3 中,我们添加了一种无需 eval 进行内联配置的新方法(为解决此问题做准备),因此您仍然可以在 HTML 文件中包含 MathJax 配置而无需触发 eval 调用。

好的,我制作了一个补丁,删除了new Function()eval()调用。 它基于最新的开发分支,但 f220993 中列出的更改也应该能够对MathJax.js的主副本进行,如果您需要这样做的话。 您确实需要允许内联样式(确实无法绕过)。 还有一个对about:blank的字体引用,以便 MathJax 可以测试对丢失字体的响应(无需进行网络访问),因此您可能需要将about:添加到font-src也是如此。 一旦我改变了这两个,这个 MathJax 的副本就可以顺利运行。

好的! 我明白为什么您肯定需要'unsafe-inline'样式。

script-src 'unsafe-inline'权限而言,如果我理解正确的话,脚本只会在用户包含内联 MathJax 配置开始时才会内联。 这会很好,因为在script-src中没有'unsafe-inline'一切仍然可以工作。 不过,应该在文档中提到它。

您对内联脚本的理解是正确的。 您不需要script-src 'unsafe-inline' ,除非您使用的是不需要使用的内联配置块。 您可以使用本地 MathJax 配置文件(添加到config= ),也可以使用普通脚本文件将MathJax变量设置为通常传递给MathJax.Hub.Config()的对象

var MathJax = {
  tex2jax: {
    inlineMath: [['$','$'],['\\(','\\)']],
    procesEscapes: true
  }
};

进入一个名为mathjax-config.js的文件,然后

<script src="mathjax-config.js"></script>
<script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>

我希望这能满足您的要求。

确实如此。 感谢您的快速修复!

这里有些人会说这不是那么快(这个问题已经开放了两年!),但我确实已经将它标记为下一个版本,并且无论如何都只是开始着手,所以你的评论来自适当的时间。

=> 合并。

那么有没有人要求github允许mathjax呢? 仍然不可能编写一个 dotjs 文件,让我在 github 问题中编写 tex,以便使用 mathjax 进行渲染......

(此处的示例 - http://stackoverflow.com/questions/16889421/how-to-insert-javascript-to-enable-mathjax-on-github-wiki-pages - 失败。)

你好,

我目前在 github 页面上托管一个 jekyll 站点并关注这篇文章,并将以下内容添加到我的包含文件中:

<script type="text/javascript"
  src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>

这应该适用于 https 或 http。 但是,当在浏览器上使用 https 加载我的博客时,它看起来一团糟,直到您单击以允许不安全的脚本。 我怎样才能解决这个问题?

@silky没有什么特别的 AFAWK。 我认为客户端不太可能,但 MathJax-node 可以提供一个高效的替代方案。

@diego898一般问题更适合http://groups.google.com/forum/#!forum/mathjax -users; 始终包含指向实时页面、浏览器和操作系统细节等的链接。谢谢。

@pkra我知道我只是不确定这是与此问题相关的错误,还是我的配置问题

@diego898没问题。 您所描述的听起来与此问题无关。

我仍然看到这个问题。 请参阅https://github.com/mathjax/MathJax/issues/1988。

@kaushalmodi ,请参阅我上面关于如何避免该问题的评论,或我对您链接到的问题的评论。 如果您使用限制脚本执行的 CSP,则必须更改配置 MathJax 的方式。

原始问题中的 (2) 是否已解决? 似乎mathjax v3仍然插入

此页面是否有帮助?
0 / 5 - 0 等级