用于评估简单数学字符串的JavaScript,如5 * 1.2(eval / white-list?)

时间:2012-03-28 19:23:02

标签: javascript math onchange

我有一个输入onchange,可将05008等数字转换为5,008.00

我正在考虑对此进行扩展,以便进行简单的计算。例如,45*5会自动转换为225.00

我可以使用字符白名单()+/*-0123456789.,然后将结果传递给eval,我认为这些字符可以安全地防止任何危险的注入。假设我使用了适当的try / catch,因为可能会创建语法错误。

  • 这是一个好的白名单,然后将其传递给eval吗?

  • 建议修改白名单

  • 您是否建议采用不同的方法(可能已经有了这样做的功能)

    我宁愿保持轻量级。这就是我喜欢eval / white-list方法的原因。代码很少。

你推荐什么?

3 个答案:

答案 0 :(得分:3)

白名单对我来说是安全的,但这不是一个简单的问题。在某些浏览器中,例如,像这样的eval-string:

/.(.)/(34)

相当于:

new RegExp('.(.)').exec('34')

因此返回数组['34','4']。这是“安全的”吗?

因此虽然可以使方法安全地工作,但这可能是一个非常棘手的主张。如果你继续这个想法,我认为你应该使用很多更积极的方法来验证你的输入。你的原则应该是“这是一个明确定义的字符串集合中的成员,已知为'安全'”,而不是“这是一个不明确的字符串集合的成员,排除了所有已知的'不安全的字符串“”。此外,为了避免操作员偷看您没有考虑的任何风险(例如+++=或诸如此类),我认为您应该在每个非数字前面插入一个空格 - 非 - 字符;并且为了避免括号触发函数调用的任何风险,我认为你应该自己处理它们,重复用空格替换(...)加上评估...的结果(确认结果是一个数字后)加上一个空格。

(顺便说一下,=怎么会出现在你的白名单中?我只是无法弄清楚那对你有用的东西!)

答案 1 :(得分:2)

鉴于极端限制性的白名单,除了抛出异常之外,我看不到任何执行恶意行为的方法。 bracket trick无效,因为它需要方括号[]

也许最安全的选择是将页面的默认值解析器修改为仅接受数字并丢弃其他任何内容。这样,链接中潜在的恶意代码永远不会进入eval

这只会让用户在某个字段中输入恶意内容的可能性,但为什么还要担心呢?用户已经可以访问他们可以用来执行任意代码的控制台(开发工具)。

答案 2 :(得分:0)

eval常常被忽视的一个问题是它会导致javascript minifiers出现问题。

像YUI这样的一些缩小器采用安全路径并在看到eval语句后立即停止重命名变量。这意味着你的javascript会起作用,但你的压缩文件会比它需要的大。

其他类似Google Closure Compiler会继续重命名变量,但如果你不小心他们可能会破坏你的代码。您应该避免将带有变量名称的字符串传递给eval。例如。

var input = "1+2*3";

var result = eval("input"); // unsafe

var result = eval(input); // safe