对 `eval` 进行清理以防止其改变任何值

15 浏览
0 Comments

对 `eval` 进行清理以防止其改变任何值

这只是一个前端而不是后端的想法,我也承认这是个糟糕的想法。目前我只是好奇。

我有一张记录表。我希望用户能够输入一个JavaScript条件语句,然后将其应用于表格以过滤记录。

例如,要过滤掉名称少于6个字符的记录,我可以输入:

record.name.length < 6

在不使用外部库的情况下,我发现使用eval是最简单的方法。然而,使用eval,当然会引入用户破坏代码的风险(虽然这只是前端,但仍然是用户体验问题)。

我希望对用户的输入进行清理,以防止其改变任何值。到目前为止,我认为只需要做这两件事来使eval“安全”:

  • 将任何单个等号=变成双等号或三等号
  • 删除或转义括号( )

处理完这两项之后,还需要做些什么来防止用户输入改变值吗?

0
0 Comments

这段代码中,作者提到了一个问题:使用`eval`函数时,`Window`对象的一些键可能会导致`Function.apply`函数出错。为了解决这个问题,作者对可能导致出错的键进行了过滤,并在代码中给出了解释。

作者首先创建了一个名为`windowKeys`的数组,其中包含了`Window`对象中的所有键。通过对这些键进行过滤,作者筛选出了一些可能导致`Function.apply`出错的键。在过滤过程中,作者尝试了将每个键作为参数传递给`Function.apply`并执行,如果执行成功则将该键保留在数组中,否则将其过滤掉。这样做的目的是为了排除一些特殊的键,如以数字开头的键、包含特殊字符或破折号的键等。

然后,作者定义了一个名为`safeEval`的函数,用于安全地执行`eval`函数。该函数接受两个参数:`code`和`context`。在函数内部,作者首先获取了`context`对象中的所有键,并将它们与`windowKeys`数组和一个字符串模板拼接在一起,形成一个新的参数数组。接着,作者尝试将这个新的参数数组作为参数传递给`Function.apply`函数,并创建一个新的函数`fn`。最后,作者将`context`对象中的值作为参数传递给`fn`函数,并返回执行结果。

在代码的最后,作者给出了两个示例:一个是简单的表达式求值,另一个是尝试访问`window`对象。通过调用`safeEval`函数,我们可以安全地执行表达式求值,并且不会受到`Window`对象中特殊键的影响。

还有另一种解决方法:在跨域的`iframe`中运行`eval`并通过`window`消息获取结果。这种方法的具体实现方式没有在代码中给出。

总之,这段代码中的问题是使用`eval`函数时可能会受到`Window`对象中特殊键的影响,作者通过过滤这些特殊键并重新构造参数数组的方式解决了这个问题。通过这种方式,我们可以安全地执行`eval`函数,而不会改变任何值。另外,还有另一种解决方法,即在跨域的`iframe`中运行`eval`并通过`window`消息获取结果。

0
0 Comments

eval函数的使用在某些情况下可能会导致安全问题,因此需要进行消毒以防止它修改任何值。解决方法是使用Function构造函数来替代eval函数。Function构造函数可以根据函数的字符串和参数名列表构建一个函数。与eval函数不同的是,使用Function构造函数构建的函数无法访问调用Function构造函数的局部作用域中的变量,因此更加安全。

然而,全局变量是可以被这个函数访问的。如果希望某些全局变量对函数不可见,可以将这些全局变量的名称作为参数传递给函数,并使用虚假值调用函数,从而覆盖这些全局变量的值。

除了全局变量,可能还有一些变量(如record)需要被javascript代码访问。可以使用Function构造函数的参数名参数来实现。假设已经存在一个名为myArguments的对象,其中包含了这些变量的值。可以通过获取myArguments的属性名和window对象的属性名,将它们合并为参数名的列表。然后,通过获取myArguments的属性值作为参数值列表。使用这些参数名和参数值列表,可以调用Function构造函数来创建一个函数。

需要注意的是,在调用这个函数时,需要确保jsString中不包含对this的引用,以防止用户进行恶意操作。可以将this的值设置为一个空对象来避免这个问题。

可以通过使用Function构造函数来替代eval函数,并使用参数名和参数值来限制函数的访问范围,从而解决eval函数可能导致的安全问题。

0