当前位置: 首页 > 知识库问答 >
问题:

清理“eval”以防止其更改任何值

郎弘业
2023-03-14

这只是前端,而不是后端。我也承认这是个坏主意。在这一点上,我只是好奇。

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

例如,要筛选出名称少于6个字符的记录,我可以输入:

record.name.length

如果不使用外部库,我发现最简单的方法就是使用eval。然而,在使用eval时,我当然会引入用户破坏代码的风险(这不是一个大问题,因为这只是前端问题,但仍然是一个用户体验问题)。

我想清理用户输入,使其无法更改任何值。到目前为止,我相信我只需要做这两件事就可以使eval“安全”:

  • 将任何单等号=转换为双等号或三等号
  • 删除或转义括号()

有了这两项,我还需要做些什么来防止用户输入改变值?


共有1个答案

穆飞星
2023-03-14

一种比eval更安全的方法是使用函数构造函数。据我所知,这个答案是完全安全的,但很可能有一些我不知道或忘记的警告,所以如果我错了,每个人都可以自由回答。

function(x, y) {
    return x + y;
}

可以写成

new Function('x', 'y', 'return x + y;')

或者干脆

Function('x', 'y', 'return x + y;')

注意,尽管函数体可以访问函数定义中声明的变量,但它不能从调用函数构造函数的本地范围访问变量;在这方面,它比eval更安全。

例外是全局变量;这些都是功能体可以访问的。也许你希望他们中的一些能够被访问;对他们中的许多人来说,你可能没有。但是,有一种方法可以解决这个问题:将全局变量的名称声明为函数的参数,然后调用函数,用假值覆盖它们。例如,请注意,此表达式返回全局对象

(function() { return Object; })()
(function(Object) { return Object; })('not Object')

因此,要创建一个不能访问任何全局变量的函数,只需调用javascript字符串上的函数构造函数,参数以所有全局变量命名,然后为所有全局变量调用一些无害的值。

var myArguments = {
    record: record
};

(顺便说一句,不要称它为arguments,因为这是一个保留字。)现在我们需要函数的参数名列表。有两种类型:来自myArguments的参数和我们要覆盖的全局参数。方便的是,在客户端javascript中,所有全局变量都是单个对象中的属性,window。我相信使用它自己的属性就足够了,没有原型属性。

var myArgumentNames = Object.keys(myArguments);
var globalNames = Object.keys(window);
var allArgumentNames = myArgumentNames.concat(globalNames);
var myArgumentValues = myArgumentNames.map(function(key) {
    return myArguments[key];
};

我们不需要为全局函数做值部分;如果我们不这样做,它们将全部设置为undefined。(哦,不要执行Object.keys(myArguments).map(…),因为数组出现的顺序有(很小)可能是错误的,因为Object.keys不能保证其返回值的顺序。您必须使用相同的数组,myArgumentNames)然后调用函数构造函数。由于函数有大量参数,因此不可能将它们全部显式列出,但我们可以使用函数上的apply方法来解决这一问题:

var myFn = Function.apply(null, allArgumentNames.concat([jsString]))

现在我们用我们生成的参数列表调用这个函数,再次使用apply方法。对于这一部分,请记住,jsString可能包含对this的引用;我们希望确保不会帮助用户进行恶意操作。脚本中的this值是apply的第一个参数。实际上这并不完全正确-如果jsString不使用严格模式,那么尝试将this设置为undefinednull将失败,而this将是全局对象。您可以通过强制脚本进入严格模式(使用“use strict”\n“jsString)来解决此问题,或者将设置为空对象。这样地:

myFn.apply({}, myArgumentValues)

 类似资料:
  • 我是新来的反应钩。并且当我从一节跳到另一节时会显示此警告。不用等它完成就能上马。 index.js:1警告:无法对未挂载的组件执行React状态更新。这是一个no-op,但它表明您的应用程序中存在内存泄漏。若要修复,请取消useEffect清理函数中的所有订阅和异步任务。在FadeItems(在AboutSection.jsx:32)在div(由CardBody创建)在CardBody(在Abou

  • 我正在研究Spring3.1注释缓存,ehcache作为缓存实现。 一个返回值像这样的方法 我第一次得到了一个myject返回值,它是可编辑的。ehache可以通过设置“拷贝读取”或“拷贝写入”来做些什么。它将强制序列化读/写对象。但是在第一次Spring不会从缓存中获取值,它总是返回通过方法本身。 是否有某种方法可以获取只读返回值?

  • 问题内容: 保存hibernate对象时,hibernate中是否有设置可以 忽略 属性的 空值 ? 注意 在我的情况下,我正在通过杰克逊将JSON反序列化为Hibernate Pojo。 JSON仅包含Pojo的某些字段。如果保存Pojo,则不在JSON中的字段在Pojo中为null,然后hibernate更新它们。 我遇到了这个问题,但这不是100%的解决方案。 http://docs.jbo

  • 我正在使用jQuery手风琴来隐藏一些数据。 accordion标题是一个带有一些标题的表格。有一个标题,我不希望你点击它,因为手风琴事件会触发。 所以 手风琴是可折叠的,如果您单击Test2(类nofunction),手风琴事件不应触发。但是如果您单击Test或其他表头,手风琴应该会触发事件。 我可以添加这个功能吗? 更新测试http://jsfiddle.net/e3Q8d/,包括jQuery

  • 为什么不能正确解析?我能给它指示吗? 解析代码:

  • 问题内容: 我现在正在使用Eclipse进行项目,并且我在bin文件夹中保存了一些资源文件(例如,图像,文本),并且程序需要这些文件。 但是,对于每次构建,Eclipse都会尝试清理文件夹,然后重新构建项目。清理时,它将删除文件夹中的资源文件。无论如何,有什么方法可以阻止Eclipse这样做呢? 我知道我可以更改文件的位置,但是我也很好奇为什么Eclipse会这样做,并且可以防止这种情况发生。 谢