为什么使用JavaScript eval函数不是一个好主意?
eval函数是一种动态生成代码的强大而简便的方法,那么有哪些警告?
解决方案
回答
我相信这是因为它可以从字符串执行任何JavaScript函数。使用它可以使人们更容易地将恶意代码注入应用程序。
回答
主要是,它很难维护和调试。就像是" goto"。我们可以使用它,但是它使查找问题变得更加困难,并且使以后可能需要进行更改的人员变得更加困难。
回答
如果传递有效的用户输入,通常这只是一个问题。
回答
除非我们100%确定要评估的代码来自受信任的来源(通常是我们自己的应用程序),否则这是使系统遭受跨站点脚本攻击的肯定方式。
回答
除了在执行用户提交的代码时可能出现的安全问题外,大多数时候,还有一种更好的方法,该方法不涉及在每次执行代码时都重新解析代码。匿名函数或者对象属性可以代替eval的大多数用法,并且更安全,更快捷。
回答
- 不正确地使用eval会打开代码以进行注入攻击
- 调试可能更具挑战性(没有行号等)
- 评估的代码执行速度较慢(没有机会编译/缓存评估的代码)
编辑:正如@Jeff Walden在评论中指出的那样,今天#3的真实性要比2008年低。但是,尽管可能会缓存一些已编译脚本,但这仅限于未经修改就重复的脚本。更有可能的情况是,我们正在评估每次都经过略微修改且因此无法缓存的脚本。我们只说某些评估代码的执行速度较慢。
回答
随着下一代浏览器以某种JavaScript编译器的形式出现,这可能会成为一个更大的问题。在这些较新的浏览器上,通过Eval执行的代码的性能可能不如JavaScript的其余部分好。有人应该做一些分析。
回答
我想到两点:
- 安全性(但是,只要我们生成要自己评估的字符串,这可能就不是问题了)
- 性能:除非要执行的代码未知,否则无法对其进行优化。 (关于javascript和性能,当然是Steve Yegge的介绍)
回答
除非我们让eval()动态内容(通过cgi或者输入),否则它与页面中所有其他JavaScript一样安全可靠。
回答
将用户输入传递给eval()会带来安全风险,但是每次调用eval()都会创建一个新的JavaScript解释器实例。这可能是资源浪费。
回答
这可能会带来安全风险,执行范围不同,效率很低,因为它会为代码执行创建全新的脚本环境。有关更多信息,请参见此处:eval。
但是,它非常有用,与审核一起使用可以添加许多良好的功能。
回答
这大大降低了我们对安全性的信心。
回答
只要我们知道在其中使用什么上下文,就不一定很糟糕。
如果应用程序正在使用eval()从某个JSON创建对象,而该JSON从XMLHttpRequest返回到我们自己的站点(由受信任的服务器端代码创建),则可能不是问题。
无论如何,不受信任的客户端JavaScript代码不能做太多事情。只要我们正在执行eval()
的东西来自合理的来源,就可以了。
回答
评估并不总是邪恶的。有时它是完全合适的。
但是,eval在当前和历史上被不知道自己在做什么的人过度使用。不幸的是,这包括编写JavaScript教程的人员,在某些情况下,这的确可能带来安全后果,或者更常见的是简单的错误。因此,我们可以做的越多,就对eval提出问号越好。每次使用eval时,我们都需要检查自己在做什么,因为我们可能会以更好,更安全,更干净的方式进行操作。
举一个非常典型的例子,设置一个元素的颜色,并将其ID存储在变量" potato"中:
eval('document.' + potato + '.style.color = "red"');
如果上面的代码类型的作者对JavaScript对象的工作原理有一定的了解,那么他们将意识到可以使用方括号代替文字点名,从而避免了eval的需要:
document[potato].style.color = 'red';
...这更容易阅读,而且潜在的错误更少。
(但是,/真正/知道自己在做什么的人会说:
document.getElementById(potato).style.color = 'red';
这比直接从文档对象中访问DOM元素的狡猾老技巧更可靠。)
回答
要记住的一件事是,我们经常可以在其他受限制的环境中使用eval()执行代码,阻止特定JavaScript功能的社交网站有时可以通过在eval块中将它们分解而被愚弄-
eval('al' + 'er' + 't(\'' + 'hi there!' + '\')');
因此,如果我们正在运行某些JavaScript代码(否则可能不允许这样做)(Myspace,我在看着我们...),那么eval()可能是一个有用的技巧。
但是,由于上述所有原因,我们不应该将其用于自己的代码,因为在这里我们可以完全控制它,只是没有必要,而且最好将其降级为"棘手的JavaScript技巧"。
回答
如果我们希望用户输入一些逻辑函数并求与与或者,则JavaScript eval函数是理想的选择。我可以接受两个字符串和eval(uate)string1 === string2
等。