2015-08-28 48 views
3

我使用流星,我很担心可能的安全漏洞。我只希望用户能够创建修改数据库中的某些字段。在这个例子中,我希望他们能够创建或更新的唯一内容是一个派对的namedescription字段。如何只允许某些文档字段在Meteor中插入和更新?

Parties.allow({ 
    insert: function (userId, party) { 
    return userId && party.owner === userId; 
    }, 
    update: function (userId, party, fields, modifier) { 
    return userId && party.owner === userId; 
    }, 
}); 

这是我在角流星教程看到的代码,但它看起来像有人可以添加使用Minimongo他们在控制台通缉的浏览器的任何字段。有没有一种方法可以轻松定义可以使用的字段,并拒绝所有不使用这些字段的插入和更新?我可以写一个简单的函数,这是否更新:

function ensureFieldsAreOk(acceptableFields,fieldsInQuestion){ 
    for(i = 0; i < fieldsInQuestion.length; ++i){ 
     if(acceptableFields.indexOf(fieldsInQuestion[i]) === -1){ 
      console.log("Hacking attempt detected"); 
      return false; 
     } 
    } 
    return true; 
} 

要INSERT命令我可以用用Object.keys(party)作为可接受的字段列表同样的功能做到这一点。

我无法想象我是第一个想到这件事的人;必须有一个处理这个问题的标准方法。

+0

或者,你可以考虑[使用方法]( https://stackoverflow.com/questions/27330321/meteor-method-vs-deny-allow-rules)。 –

回答

1

我没有看到这样做有什么问题,我不知道任何更合适的方式。尽管使用下划线可以减少测试的难度:

Parties.allow({ 
    insert: function (userId, party) { 
    return userId && party.owner === userId 
      && _.difference(_.keys(party), acceptableFields).length == 0; 
    }, 
    update: function (userId, party, fields, modifier) { 
    return userId && party.owner === userId 
      && _.difference(fields, acceptableFields).length == 0 
    } 
}); 
1

不用担心,您的问题完全有效。我在Meteor应用程序中处理这个问题的方式是筛选正在插入或更新的文档。由于传递给insertupdate权限函数的参数不同,我插入和更新的方法不同。

我建议直接使用下面的代码或类似的,以适应您可能已经根据您的标准上面指定的任何其他需要的东西:

Parties.allow({ 
    insert: function(userId, doc) { 
     var allow = true; 

     if(!userId || doc.owner !== userId) { 
      allow = false; 
     } 

     Object.keys(doc).forEach(function(docKey) { 
      if(acceptableFields.indexOf(docKey) < 0) { 
       allow = false; 
      } 
     }); 

     return allow; 
    }, 
    update: function(userId, doc, fieldNames, modifier) { 
     var allow = true; 

     if(!userId || doc.owner !== userId) { 
      allow = false; 
     } 

     fieldNames.forEach(function(fieldName) { 
      if(acceptableFields.indexOf(fieldName) < 0) { 
       allow = false; 
      } 
     }); 

     return allow; 
    } 
}); 

,你可以在代码示例中看到的,我已经包括检查用户是否已登录,以及用户是否是他们试图插入或更新数据库的文档的所有者。此外,insert函数直接检查文档的关键字(显然,如果必须检查比顶级关键字更深的关键字,比如我的代码示例,则可以进行更彻底的检查),并且在列表中未包含任何关键字可接受的领域。对于update函数,由于doc参数是未更改的文档,因此您需要检查fieldNames参数。与insert函数一样,如果您需要对比顶级密钥更深入的密钥执行检查,则可以直接检查modifier参数并挖掘插入尝试中引用的每个密钥。对于您可能需要的所有信息来确定最终解决方案的外观,请查看Meteor文档的this section

最后,我写了我的答案,使用通用的Javascript,以防你想采取的路线。显然,你可以使用像Underscore和其他库来增强我的建议。