我想动态构建我的查询并使用以下代码段:
--snip--
module.exports = {
get : function(req, res, next) {
var queryStr = "req.database.table('locations').get(parseInt(req.params.id))";
if (req.params.id) {
if (req.fields) {
queryStr += '.pick(' + req.fieldsStr + ')';
}
console.log(queryStr);
eval(queryStr).run(function(result) {
console.log(result);
res.send(result);
});
} else if (!req.params.id) {
--snip--
然而,引入eval会打开我的代码注入(req.fields填充url参数),我看到我的应用程序的响应时间从7秒增加到11毫秒
有没有更聪明的方法来完成我在这里所做的事情?
请建议。
答案 0 :(得分:1)
如果我理解正确,你应该使用以下内容:
--snip--
module.exports = {
get : function(req, res, next) {
var queryResult = req.database.table('locations').get(parseInt(req.params.id));
if (req.params.id) {
if (req.fields) {
queryResult = queryResult.pick.apply(queryResult, getFields(req.fieldsStr));
}
queryResult.run(function(result) {
console.log(result);
res.send(result);
});
} else if (!req.params.id) {
--snip--
其中getFields
类似于:
var fields = {
'name': name,
'address': address,
'zipcode': zipcode
// ...
};
function getFields(str) {
return str.split(',').map(function(u) {
return fields[u];
});
}
当然,如果req.fields
本身就是一个字符串数组,您可以使用它而不是拆分req.fieldsStr
。
答案 1 :(得分:1)
与每次(或大多数)注射一样,最佳解决方案是具有预定义的可能字段列表。例如:
var predefined_fields = [ "id", "name", "age" ];
if (predefined_fields.indexOf( req.fieldsStr ) !== 0) {
// do something
}
此外,您可以在parseInt(req.params.id)
之外推送queryStr
:
var id = parseInt(req.params.id);
var queryStr = "req.database.table('locations').get("+id+")";
解决了第二次注射问题。
当然,将来可能会有点复杂,所以我建议编写(或使用)某种查询生成器。
我不知道你正在使用的库,但它看起来像你可以简单地进行查询而没有字符串连接和eval。毕竟这个.run
方法代表什么,对吧?这将极大地提高性能和安全性。
编辑您似乎根本不需要这些字符串。这应该有效:
var query = req.database.table('locations').get(parseInt(req.params.id));
if (req.params.id) {
if (req.fields) {
query = query.pick( req.fieldsStr );
}
console.log(queryStr);
query.run(function(result) {
console.log(result);
res.send(result);
});
}
安全高效。 :)