Javascript eval (和朋友们)
Javascript eval (and friends)
有些人声称 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
的主要批评是它是矫枉过正的 - 你正在使用大锤拍打苍蝇,而来自过度工具的所有额外风险 - 它们可以反弹并击中你。
让我们将响应类型分为几个不同的类别:
- 按需加载静态 JavaScript
- 来自安全通道上受信任源的动态响应,其中不包含不受信任方指定的任何内容。
- 来自混合源(可能大部分受信任,但包括不受信任方指定的编码字符串(的动态响应,主要是数据
- 基于数据的副作用
对于(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
,只要确保你分开负责。
编辑:
我看到了这种逻辑的缺陷。服务器显然是在告诉客户端该怎么做,仅仅是因为它提供了客户端执行的脚本。但是,我的观点是服务器端代码不应该动态生成脚本。服务器应该是编排的,而不是生产的。
- 递归使用 eval() 是检查程序执行的好方法吗?
- 为什么忽略了eval()代码中的语法错误
- 我需要为我的朋友在这个项目上提供帮助
- 推荐在JavaScript中执行存储为字符串的函数,而不是使用eval
- Javascript eval()无法处理传递的字符串
- 调用绕过eval()的函数
- Semi-sandboxing Javascript eval
- ES6 模板文字是否比 eval 更安全
- JavaScript 可以在这里使用 eval 吗?
- 如何使用uglifyjs/uglifyjs2解析walk和eval javascript表达式
- 如何使用其他地方指定的访问信息访问嵌套的json对象,而不使用eval或迭代
- 当eval只执行服务器端数据时,在javascript中使用eval是否安全
- 使用eval()定义变量显示未定义的错误
- javascript eval方法语法
- 在Javascript中使用eval的替代方案
- Eval vs execscript
- eval()读取函数参数有多糟糕
- 使用eval()设置全局变量
- 分析CSV中的15行时出错-Can'我不知道为什么——我的朋友们也不知道
- Javascript eval (和朋友们)