【问题标题】:What is a secure way to prevent a user from updating specific fields in a MongoDB document?防止用户更新 MongoDB 文档中特定字段的安全方法是什么?
【发布时间】:2017-03-24 05:08:32
【问题描述】:

我试图阻止用户更新 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")}}

这种方法非常简单,而且似乎很有效。我想联系社区,看看有没有其他人以前解决过这个问题,或者看到我的方法有明显的缺陷。谢谢,

约书亚

【问题讨论】:

  • 是否有一组不同的字段可供每个用户编辑?如果您可以展示一个示例文档,那可能会使您的提案更清晰。
  • 我编辑了这个问题,以澄清用户可以以他们想要的任何方式编辑文档,除了我想要保护的某些字段。一个示例文档是:{"name": "test_object", "permissions": {"Joshua": ["AttributeA", "AttributeB"], "John": ["AttributeA"]}}。在此示例中,用户可以编辑名称、删除字段名称、添加字段“电话”,或者通常他们想要的任何内容,除了编辑权限字段。

标签: mongodb mongodb-query


【解决方案1】:

没有看到一些示例数据解释什么应该/不应该更新 - 很难确定,但我防止这种情况的方法是允许用户直接提供他们将要更新的字段。例如,假设您有一个名为update_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})

这样您就可以完全控制数据库中的更新内容。所以如果传入了额外的字段(如salary),就会被忽略。

【讨论】:

    【解决方案2】:
    1. 由于(据我所知)没有字段锁定,在这种情况下您可以做的是创建一个例程来获取特定文档,以您希望的任何方式将其呈现给用户,但只显示允许他们编辑的字段。

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

    3. 如果您遵循的方案确实具有前缀 e_address,您已决定任何带有 e_ 的字段都允许编辑,那么以编程方式工作会容易得多。

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

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

    (由于我不使用 Python,我将这个答案保持通用,尽管该结构应该适用于任何语言。)

    【讨论】:

    • 我知道 MongoDB 在密钥字符串 (idontplaydarts.com/2011/02/mongodb-null-byte-injection-attacks) 中容易受到空字节注入攻击。通过将字符串的开头与子字符串进行比较,我认为我正在保护自己免受这种攻击。您的示例是否可以防止这种特定的攻击?
    • @Joshua 甚至在您最后引用的文章中说:“最好的解决方案是严格验证您允许用户传递给集合的字段,另外检查每个用户提供的数据库和集合存在空字节的字符串。”如果您查看我在回答中写的内容,请在记忆中做所有事情。之后检查每个字段,您需要使用函数检查允许的编辑和空字节(以及您需要的任何其他验证。)在内存中强制更新不允许直接接触集合,直到代码验证它。
    猜你喜欢
    • 1970-01-01
    • 2018-05-24
    • 2013-01-06
    • 1970-01-01
    • 2022-01-20
    • 2016-02-15
    • 1970-01-01
    • 1970-01-01
    • 2019-04-17
    相关资源
    最近更新 更多