JavaScript 具有某些限制,例如阻止读取和写入磁盘以及不允许访问其他浏览器窗口或域。但这就是防止恶意代码运行所需的全部内容吗?
JavaScript 非常强大,浏览器会毫无疑问地运行它们提供的所有 JavaScript 代码,这似乎很奇怪。那怎么安全?
JavaScript 具有某些限制,例如阻止读取和写入磁盘以及不允许访问其他浏览器窗口或域。但这就是防止恶意代码运行所需的全部内容吗?
JavaScript 非常强大,浏览器会毫无疑问地运行它们提供的所有 JavaScript 代码,这似乎很奇怪。那怎么安全?
该标准旨在确保安全。实施可能不是。
浏览器隔离 JavaScript,因为它在浏览器进程本身内执行。它不能做任何浏览器 JavaScript 解释器或JIT 编译器不允许的事情。然而,由于其复杂性,发现允许 JavaScript 危害浏览器并利用浏览器进程权限获得任意代码执行的漏洞并不少见。
因为这些类型的安全漏洞非常普遍,所以许多浏览器都会实现沙箱。这是一种保护机制,试图隔离受感染的浏览器进程并防止它造成进一步的伤害。沙盒的工作方式取决于浏览器。Firefox 的沙盒功能非常有限,而 Chrome 和 Edge 具有重要的沙盒功能。然而,尽管有这种深度防御,浏览器漏洞通常可以与沙盒逃逸漏洞结合使用。
有关 Firefox 与 Chromium 的更多信息,请参阅https://madaidans-insecurities.github.io/firefox-chromium.html。
它如何安全?
它不是。或者更确切地说,它与浏览器实现一样安全。浏览器(包括它们的 JavaScript 引擎)是复杂的软件,会定期添加新功能——因为用户需要它们。
这意味着,即使知名公司肯定有质量程序来针对已知漏洞测试他们的代码,但在实现功能时存在未被检测到的缺陷的风险始终存在。
目前,公认的方式是,一旦检测到违规,就会发布包含修复的新版本。但是在发现漏洞和安装修复程序之间,浏览器是易受攻击的。这就是为什么建议保持浏览器最新的原因,以便只暴露于零日漏洞。
确实,在 JavaScript 级别,浏览器被设计为对正在执行的代码进行沙箱处理(主要是不暴露任何危险的 API),但是 JavaScript 是一种非常复杂的解析和执行语言。
ECMAScript 是 JavaScript 背后的标准,由于我们今天正在经历的对初学者友好的编程语言的巨大营销膨胀,ECMAScript 正在快速更新并引入越来越复杂的功能来实现运行时。
反过来,这扩大了攻击的范围并允许错误潜入。
一个很好的例子是Patrick Biernat、Markus Gaasedelen、Amy Burnett最近为 pwn2own 2018 所做的工作。
http://blog.ret2.io/2018/06/05/pwn2own-2018-exploit-development/
该博客描述了一个 0day 的发现,它允许在 WebKit 中执行任意代码,以及如何利用 macOS 窗口管理器中的另一个 0day 来逃避 Safari 正在运行的沙箱(这是一个 macOS 沙箱,而不是 Safari 的沙箱)升级到“root”并拥有系统。
长话短说,只需在启用 JavaScript 的情况下访问一个链接,macOS 系统就可以完全被攻破,而不会出现任何用户可见的故障。
这就是 JavaScript 的安全性:与 WebKit 的 JSCore 一样复杂的软件一样安全。
这就是为什么建议需要高安全性的用户禁用 JavaScript(例如,这是 DarkWeb 中相当普遍的要求)。
上述作者在 WebKit 中发现的漏洞是新引入的垃圾收集器和函数之间的竞争条件array.reverse
:如果 GC 在反转数组时开始标记数组,则可能导致 UAF(Use After Free)漏洞利用。标记是在数组上按顺序完成的,假设反向时GC正好在数组的中间,那么后半部分永远不会标记并因此被选中进行收集,从而导致UAF(数组对象本身没有被收集,只有它的元素)。
如何使用 UAF 生成更强大的可导致任意代码执行的漏洞利用原语或多或少是相同技术的变体:首先在新释放的空间(例如数组)中分配一个有趣的对象,然后是 RW 原语创建(例如通过更改数组的边界),最后将任意操作码写入内存(例如在 JITted 页面中)。
这个特定 0day 的详细信息在链接的博客中。
有趣的部分是这个 0day 的发现方式:由于 WebKit 如此之大,如果不付出巨大的努力,深入的代码审查是不可能的,因此设置了自动抖动。
这必须让我们反思这样一个事实,即当我们有数十万或数百万行代码时,很难让每个代码都表现得很好。
如其他答案所述,每个浏览器都有自己的脚本引擎,旨在沙箱 JavaScript 执行,每个引擎都试图限制可能导致恶意行为的 JavaScript 功能。
但作为一项规则,JavaScript 在浏览器中从来都不是安全的。恶意代码开发人员不断寻找方法来利用每个引擎的工作方式及其可用的 JavaScript 功能来实现恶意目标。
在最初的几年里,JavaScript 在浏览器中相当危险。现在,恶意代码开发人员和浏览器/引擎开发人员之间一直存在竞争,最终恶意开发人员总是获胜,即使只是很短的时间。所以 JavaScript 很难说是安全的。“现在应该是安全的”是更准确的说法。