我正在编写一些JavaScript代码来解析用户输入的函数(用于类似电子表格的功能)。解析完公式后,我可以将其转换为JavaScript并在其上运行eval()以产生结果。

然而,我总是避免使用eval(),因为它是邪恶的(而且,无论正确与否,我一直认为它在JavaScript中更邪恶,因为要计算的代码可能会被用户更改)。

那么,什么时候可以使用它呢?


当前回答

只要可以确定代码的源代码来自您或实际用户,就没有理由不使用eval()。尽管他可以操纵发送到eval()函数的内容,但这并不是一个安全问题,因为他能够操纵网站的源代码,因此可以改变JavaScript代码本身。

所以…何时不使用eval()?Eval()只应该在第三方有可能更改它的情况下才使用。比如拦截客户端和服务器之间的连接(但如果这是一个问题,请使用HTTPS)。你不应该用eval()来解析别人写的代码,比如在论坛上。

其他回答

虽然在许多情况下,您可以通过将脚本连接在一起并动态运行来完成需要完成的任务,但您通常可以使用更强大且可维护的技术。Eval很少是正确的选择。:关联数组表示法(obj["prop"]与obj.prop相同),闭包,面向对象技术,函数技术-请使用它们。

只要可以确定代码的源代码来自您或实际用户,就没有理由不使用eval()。尽管他可以操纵发送到eval()函数的内容,但这并不是一个安全问题,因为他能够操纵网站的源代码,因此可以改变JavaScript代码本身。

所以…何时不使用eval()?Eval()只应该在第三方有可能更改它的情况下才使用。比如拦截客户端和服务器之间的连接(但如果这是一个问题,请使用HTTPS)。你不应该用eval()来解析别人写的代码,比如在论坛上。

当您使用解析函数解析JSON结构时(例如,jQuery.parseJSON),它期望JSON文件的完美结构(每个属性名都用双引号括起来)。然而,JavaScript更加灵活。因此,可以使用eval()来避免它。

在服务器端,当处理sql、influxdb或mongo等外部脚本时,eval非常有用。可以在运行时进行自定义验证,而无需重新部署服务。

例如,具有以下元数据的成就服务

{ "568ff113-abcd-f123-84c5-871fe2007cf0": { "msg_enum": "quest/registration", "timely": "all_times", "scope": [ "quest/daily-active" ], "query": "`SELECT COUNT(point) AS valid from \"${userId}/dump/quest/daily-active\" LIMIT 1`", "validator": "valid > 0", "reward_external": "ewallet", "reward_external_payload": "`{\"token\": \"${token}\", \"userId\": \"${userId}\", \"amountIn\": 1, \"conversionType\": \"quest/registration:silver\", \"exchangeProvider\":\"provider/achievement\",\"exchangeType\":\"payment/quest/registration\"}`" }, "efdfb506-1234-abcd-9d4a-7d624c564332": { "msg_enum": "quest/daily-active", "timely": "daily", "scope": [ "quest/daily-active" ], "query": "`SELECT COUNT(point) AS valid from \"${userId}/dump/quest/daily-active\" WHERE time >= '${today}' ${ENV.DAILY_OFFSET} LIMIT 1`", "validator": "valid > 0", "reward_external": "ewallet", "reward_external_payload": "`{\"token\": \"${token}\", \"userId\": \"${userId}\", \"amountIn\": 1, \"conversionType\": \"quest/daily-active:silver\", \"exchangeProvider\":\"provider/achievement\",\"exchangeType\":\"payment/quest/daily-active\"}`" } }

然后允许,

通过json中的文字字符串直接注入对象/值,对于模板文本很有用 可以用作比较,比如我们制定规则如何验证CMS中的任务或事件

缺点:

如果没有完全测试,代码中的错误可能会破坏服务中的内容。 如果黑客可以在您的系统上编写脚本,那么您就完蛋了。 验证脚本的一种方法是将脚本的散列保存在安全的地方,以便在运行之前检查它们。

当你相信消息来源时。

在JSON的情况下,它或多或少很难篡改源代码,因为它来自你控制的web服务器。只要JSON本身不包含用户上传的数据,使用eval就没有什么大的缺点。

在所有其他情况下,在将用户提供的数据提供给eval()之前,我将竭尽全力确保它符合我的规则。