如何只允许在Meteor中插入和更新某些文档字段?

时间:2015-08-28 03:25:43

标签: javascript mongodb security meteor

我正在使用Meteor,我担心可能的安全漏洞。我只希望用户能够在数据库中创建修改某些字段。对于此示例,我希望他们能够创建或更新的唯一内容是参与方的namedescription字段。

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

这是我在Angular Meteor教程中看到的代码,但看起来有人可以使用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)作为可接受的字段列表使用相同的函数。

我无法想象我是第一个想到这一点的人;必须有一种标准的方法来解决这个问题。

3 个答案:

答案 0 :(得分:1)

我没有看到这样做的任何错误,我不知道任何更合适的方式。尽管使用下划线,您可以减少测试:

typedef struct {
    int Win_Loss;
    int parent;
    int identifier;
    int Object_Moved;
    int Wolf; 
    int Goat;
    int Salad;
    int Boat;
} Node;


Node Create_Child (Node Parent_Node, int item) {
    Node Child;
    Child.Boat = (-1)*Parent_Node.Boat;
    Child.Wolf = Parent_Node.Wolf;
    Child.Goat = Parent_Node.Wolf;
    Child.Salad = Parent_Node.Salad;

    int* Child_Items[] = {&Child.Wolf, &Child.Goat, &Child.Salad, &Child.Boat};
    Child.parent = Parent_Node.identifier;
    Child_Items[item][0] *= (-1);
    Child.Object_Moved = item;
    return Child;
}

答案 1 :(得分: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等库来增强我的建议。

答案 2 :(得分:1)

要限制与集合相关联的字段,您可以使用https://atmospherejs.com/aldeed/simple-schemahttps://atmospherejs.com/aldeed/collection2

您可以定义,字段,类型,默认值和许多其他选项。

至于确保用户只能更新特定字段,您可以使用更新允许/拒绝规则中的fieldNames属性进行检查:

update: function (userId, doc, fieldNames, modifier) { 
    // check fieldNames here.
}