0

クエリを動的に作成し、次のスニペットを使用したいと思います。

--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ミリ秒に増加します。

私がここでしたことを達成するためのより賢い方法はありますか?

ご意見をお聞かせください。

4

2 に答える 2

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

于 2012-11-25T22:42:52.187 に答える
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+")";

これにより、2 番目のインジェクションの問題が解決されます。

もちろん、将来的には少し複雑になるかもしれないので、ある種のクエリ ジェネレータを作成 (または使用) することをお勧めします。

使用しているライブラリはわかりませんが、文字列の連結と評価なしで単純にクエリを実行できるようです。やはりこの.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);
    });
}

安全で効率的。:)

于 2012-11-25T22:51:59.103 に答える