JavaScript:如何安全地使用eval()

3

我正在制作一个小游戏,现在的问题是需要根据每个单位独特的能力计算数据。因此,我想我需要一个公式来实现这个目标。我不知道这是否是正确的做法,但以下是我的想法:

tip = 'Hurls a fire ball at your enemy, dealing [X] damage.';
formula = '5 * unit.magicPower * abilitylevel';

因此,对于每个单元的工具提示,我使用

tip.replace('[X]', eval(formula))

这段代码看起来可以正常工作,但我担心的是它的安全性。我曾多次听到人们不建议使用它。我使用 eval() 的方式是否存在潜在问题?


你需要使用专门用于数学计算的库,或者如果需要更多的JavaScript功能,则可以使用沙盒。这是假设这个公式是任意的。 - Brad
3个回答

5
只要控制了eval的输入,它就是安全的。当您使用它来处理您控制的输入时,问题就出现了。此时,它变得不安全,因为它是一个完整的JavaScript解析器,但有些人有时会尝试将其用作仅表达式求值器(例如,在解析来自不受控制的源的JSON时)。
另一个反对意见是它启动了一个完整的JavaScript解析器(因此理论上成本高昂),但坦率地说,除非您在紧密循环中执行数十万次操作,否则这并不重要。

4
但是说你可以控制 JavaScript 中的任何东西就像说你拥有地心引力一样。 - php_nub_qq
1
如果你正在执行 eval("5 * unit.magicPower * abilityLevel"),并且你定义了 unit 和其他变量,那么你就控制了输入。没有什么神奇的东西可以使其不安全。 - T.J. Crowder
1
在这些情况下,根本没有理由使用eval() - Brad
@Brad:是的,使用案例非常少。 - T.J. Crowder

2

eval是一种非常危险的方法,特别是当其中包含由用户提供的表达式时。如果完全使用内置组件构建,那么风险就不是很大。然而,通常还有更好的实现方式,如调用闭包函数。


3
可以说,如果输入来自当前用户,则并不危险;毕竟,他们可以打开Web控制台并执行任何操作。但是,如果您正在使用eval来评估来自不同用户的浏览器中的输入,则会变得危险。 - T.J. Crowder
@T.J.Crowder 啊,现在我明白了。那让我受益匪浅! - php_nub_qq

1
基本的经验法则是确保默认情况下只通过eval()传递你的数据/信息。
如果有人想要搞砸东西,像Firebug这样的工具是无法阻止他们的,但这就是服务器端验证的作用。
现在,如果你谈论服务器端的eval(),那么你真的必须小心。不幸的是,有很多不合作的人在JavaScript和浏览器中实现它,所以你将被迫在JavaScript中使用eval(),我从未在PHP中使用过它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接