防止用户更新MongoDB文档中的特定字段的安全方法是什么?

防止用户更新MongoDB文档中的特定字段的安全方法是什么?,mongodb,mongodb-query,Mongodb,Mongodb Query,我试图阻止用户更新mongodb对象中的某些字段,允许用户编辑其他字段。例如,用户应该能够编辑/添加/删除除“权限”字段之外的所有字段。我目前的方法是测试用户试图“$set”的每个键,看看它是否以子字符串“permissions”(覆盖点符号)开头。python中的示例: def sanitize_set(son): return {"$set": {k: v for k, v in son.get("$set", {}).items() if not k.sta

我试图阻止用户更新mongodb对象中的某些字段,允许用户编辑其他字段。例如,用户应该能够编辑/添加/删除除“权限”字段之外的所有字段。我目前的方法是测试用户试图“$set”的每个键,看看它是否以子字符串“permissions”(覆盖点符号)开头。python中的示例:

def sanitize_set(son):
    return {"$set": {k: v for k, v in son.get("$set", {}).items()
            if not k.startswith("permissions")}}
这种方法非常简单,似乎很有效。我想接触社区,看看是否有其他人以前解决过这个问题,或者看到我的方法中存在明显的缺陷。谢谢,

约书亚

  • 因为(据我所知)没有字段锁定,所以在这种情况下,您可以创建一个例程来提取特定文档,以任何您希望的方式将其呈现给用户,但只显示允许他们编辑的字段

  • 您可以向用户(编辑器)呈现整个JSON表示,并拥有一个例程,该例程不允许更改锁定的字段。换句话说,如果您不想编辑字段
    {“name”:“Sam”}
    ,即使编辑器将此值更改为
    {“name”:“Joe”}
    ,只需在更新之前将其踢出即可,并且只更新允许编辑的字段。由于在实际更新(upsert)之前都是在内存中完成的,所以您可以完全控制正在编辑的内容和未编辑的内容

  • 如果您遵循的方案确实有一个前缀,比如e_address,您已经确定任何带有e_的字段都允许编辑,那么从编程角度来说,这项工作就容易多了

  • 即使在用户定义的角色中,我也没有看到在集合中锁定特定字段的任何可能性。(我可能错了。)

  • 这里的编程结构很简单。
    A.将字段提取到内存
    B.编辑进行编辑
    C.仅更新允许编辑的字段。任何其他更改都可以忽略


  • (我保持这个答案的通用性,因为我不使用Python,尽管这个构造应该适用于任何语言。)

    没有看到一些示例数据,其中解释了什么应该/不应该是可更新的-很难确定,但是我防止这种情况发生的方法是不允许用户直接提供他们将要更新的字段。例如,假设您有一个名为
    update\u employee
    的函数,用于更新员工文档中的信息。如果您这样实现它:

    update_employee(employee):
       db.employees.update({_id: session.user_id}, {$set: employee})
    
    作为
    employee
    对象传入的任何内容都将被更新。相反,您可以使用传入的值创建更新对象,如下所示:

    update_employee(employee):
       updatedEmployee = {
          email: employee.email,
          address: employee.address,
          phone: employee.phone
       }
       db.employees.update({_id: session.user_id}, {$set: updatedEmployee})
    

    这样,您就可以完全控制数据库中正在更新的内容。因此,如果传入了一个额外的字段(如
    工资
    ),它将被忽略。

    是否有一组每个用户都可以编辑的字段?如果您可以显示一个示例文档,这可能会使您的建议更清晰。我编辑此问题是为了澄清用户可以以任何方式编辑文档,但我希望保护的某些字段除外。一个示例文档是:{“name”:“test_object”,“permissions”:{“Joshua”:[“AttributeA”,“AttributeB”],“John”:[“AttributeA”]}。在本例中,用户可以编辑名称、删除字段名称、添加字段“phone”或除编辑权限字段外的任何其他内容。我知道MongoDB容易受到密钥字符串()中的空字节注入攻击。通过比较字符串的开头和子字符串,我认为我是在保护自己免受这种攻击。你的例子能抵御这种攻击吗?@Joshua甚至在你最后引用的文章中说:“最好的解决方案是严格验证允许用户传递给集合的字段,另外检查每个用户提供的数据库和集合字符串是否存在空字节。”如果你看看我在回答中写的,在记忆中做每件事。在此之后,使用函数检查每个字段是否允许编辑和空字节(以及需要的任何其他验证)。在代码验证之前,在内存中强制更新不允许与集合直接接触。