我的程序处理许多不同类型的文档以从中提取信息。 它有一个非常通用的结构,以适应我们使用的数百种不同类型/格式的文档。
处理器代码:
Processor.prototype.process = function(){
var self = this;
var fields = self.processor_config;
var p = {};
for(key in fields){
if(fields.hasOwnProperty(key)){
p[key]=self._processKey(fields[key]);
if(typeof(p[key])=='undefined' || p[key]===''){
self.emit('warning', {
type: 'Problem parsing Key',
msg: 'Key : '+key,
doc: self.docName
});
}
}
}
self.emit('extracted',p);
};
processKey()函数然后根据"类型"来排序要做的事情。领域:
Productor.prototype._processKey = function(cnf) {
var self = this;
var value;
if(cnf.type=="css"){
value = self._processCSSKey(cnf);
}else if(cnf.type=="regexp"){
value = self._processRegexpKey(cnf);
}else if(cnf.type=="custom"){
value = self._processCustomKey(cnf);
}
return value;
};
从每种类型的文档中提取的内容的信息来自mongodb集合:
包含两种类型字段的虚构配置:
doc_name: "FormK7",
processor_config: {
company:{
type:"css"
selector:"p",
ord:3,
attr:{type:"text",parser:""}
},
litigation:{
type:"custom"
func:"(function(){var a =['123'];return a})()"
},
}
上面的例子很没用,但真实的东西有更复杂的功能(虽然不多)。
我的自定义处理器如下:
Productor.prototype._processCustomKey = function(cnf) {
var value = eval(cnf.func);
return value;
};
我的问题是我还没有找到一种方法来处理自定义键而不使用eval。然而,简单地提到了“eval'让我想起一个愤怒的道格拉斯·克罗克福德(Douglas Crockford)的照片,让我永远地被黑暗遗忘......
其他信息:
在现实生活中,存储在mongo中的函数被缩小。
需要通用处理器,因为每种文档类型只有一个处理器会非常浪费(格式一直在变化,其中有数百种,有些仅使用一次......)。所以这些功能需要以某种方式记录。而且他们太不同了,难以被硬编码......
没有用户输入,无法从网络访问该应用。恶意用户在能够在mongo中注入代码之前可以访问服务器,因此安全问题非常严重。
所以问题如下:
在这种情况下,eval真的是邪恶的,还是一个有效的用例?有没有更好的方法/最佳实践来解决这个问题?
答案 0 :(得分:1)
您可以创建一个从mongo导出到临时文件的模块,然后使用require
导入该文件。这样你就不会进行评估,就像Bergi提到的那样,它可以防止eval
的范围问题。
此外,一旦您导出它,并在需要它之前,您可以使用类似Esprima的东西来创建代码的AST并分析它以查看它是否符合您可能具有的某些标准。 (或许,您可以禁止在作为安全措施导入的代码中使用this
- 这是ADSafe规则的一部分)