Javascript eval (和朋友们)

Javascript eval (and friends)

本文关键字:朋友们 eval Javascript      更新时间:2023-09-26

有些人声称 eval 是邪恶的。

任何常规的 HTML 页面可能如下所示:

        <script src="some-trendy-js-library.js"></script>
    </body>
</html>

也就是说,假设这样做的人知道他的工作,并将javascript留在页面末尾加载。

在这里,我们基本上是将脚本文件加载到 Web 浏览器中。有些人已经更深入地使用它作为与第三方服务器通信的一种方式......

<script src="//foo.com/bar.js"></script>

在这一点上,发现无论出于何种原因,在运行时有条件地实际加载这些脚本都很重要。

我的观点是什么?虽然机制不同,但我们在做同样的事情......将一段纯文本作为代码执行 - 又名eval() .


既然我已经明确了我的观点,那么问题来了......

给定某些条件,例如 AJAX 请求或(更有趣的是(websocket 连接,从服务器执行响应的最佳方式是什么?

这里有几个让你思考...

  • eval()服务器的输出。(那边的那个家伙是不是晕倒了?
  • 运行服务器返回的命名函数:var resp = sock.msg; myObj[resp]();
  • 构建我自己的解析器来弄清楚服务器试图告诉我什么,而不会直接弄乱JavaScript。

给定某些条件,例如 AJAX 请求或(更有趣的是(websocket 连接,从服务器执行响应的最佳方式是什么?

当用于解析消息结果时,对eval的主要批评是它是矫枉过正的 - 你正在使用大锤拍打苍蝇,而来自过度工具的所有额外风险 - 它们可以反弹并击中你。

让我们将响应类型分为几个不同的类别:

  1. 按需加载静态 JavaScript
  2. 来自安全通道上受信任源的动态响应,其中不包含不受信任方指定的任何内容。
  3. 来自混合源(可能大部分受信任,但包括不受信任方指定的编码字符串(的动态响应,主要是数据
  4. 基于数据的副作用

对于(1(,XHR+eval<script src>没有区别,但XHR+eval几乎没有优势。

对于(2(,差别不大。 如果你可以使用JSON.parse解压缩响应,你可能会遇到更少的问题,但eval的额外权限不太可能被来自可信来源的数据滥用,所以如果你有一个很好的积极理由eval,没什么大不了的。

对于(3(,有很大的区别。 eval的过度滥用权威,即使你非常小心,也很可能会咬你。 这在安全性方面很脆弱。 别这样。

对于 (4(,最好将其分为数据问题和代码问题。 如果可以在执行之前验证结果,JSONP 允许这样做。 使用JSON.parse或其他几乎没有可滥用权限的东西来解析数据,因此您编写并批准供外部使用的函数会产生副作用。 这最大限度地减少了多余的可滥用权限。 天真的eval在这里很危险。

">

邪恶"并不意味着"禁止"。 有时,有充分的理由使用所谓的"邪恶"功能。 它们被称为"邪恶",因为它们可能而且经常被滥用。

在您的情况下,客户端脚本只允许向"自己的"服务器发出请求。 这是原始JavaScript来自的同一服务器,因此动态响应与原始代码一样可信。 对于eval()来说,这是一个完全有效的方案。

如果你从一个你无法控制的域中获取代码,那么将代码"原始"交给JavaScript解释器总是意味着你必须完全信任该域,否则你必须不关心恶意代码是否破坏了你自己的页面。

如果您控制域,则随心所欲。

服务器应该为您提供数据,而不是代码。您应该让服务器使用 JSON 数据进行响应,以便您的 JS 代码可以相应地执行。让服务器发送要用myObj[resp]();调用的函数的名称仍然是将服务器逻辑与客户端逻辑紧密耦合。

如果没有一些示例代码,很难提供更多建议。

让您的服务器返回 JSON,并在客户端上解释该 JSON。客户端将弄清楚如何处理 JSON,就像服务器弄清楚如何处理客户端收到的请求一样。

如果您的服务器开始返回可执行代码,则您有问题。不是因为"坏"的事情会发生(尽管它可能(,而是因为您的服务器不负责知道客户端应该做什么或不应该做什么

这就像将代码发送到服务器并期望服务器执行它一样。除非你有一个很好的理由(比如浏览器内IDE(,否则这是一个坏主意。

尽可能多地使用eval,只要确保你分开负责。

编辑:

我看到了这种逻辑的缺陷。服务器显然是在告诉客户端该怎么做,仅仅是因为它提供了客户端执行的脚本。但是,我的观点是服务器端代码不应该动态生成脚本。服务器应该是编排的,而不是生产的。