【问题标题】:Is exposing mongodb query over REST API safe?通过 REST API 公开 mongodb 查询是否安全?
【发布时间】:2014-05-23 05:36:32
【问题描述】:

我正在为查询 MongoDB 数据库的服务构建 REST API。最初,我采用提供“/user/1”的标准路线来搜索用户 id 1 等。随着我深入到项目中,其他开发人员开始询问我们是否可以添加布尔搜索功能,例如能够做到“和”、“非”和“或”。考虑到为此创建 DSL 所需的工作量,我考虑让 REST API 接受一个 MongoDB 查询 JSON 对象,就像这样(假设这是通过 POST 传递的):

/query/{"$or": [{"user": "1", "user", "2"}]}

现在,在将该查询传递给 MongoDB 之前,我将执行以下操作:

  1. 验证 JSON 对象
  2. 确保该字符串仅用于query 函数,而不是updateruncommandaggregation
  3. 验证查询中没有$where子句since that allows script execution

这样做是否足以防止注射?阅读 MongoDB FAQ,似乎将 JSON 传递给查询操作是无害的,因为您无法使用它运行任何 javascript($where 除外)。这是一种安全的方法吗?

【问题讨论】:

标签: mongodb


【解决方案1】:

正如您已经注意到的,由于 JSON 解析的性质,MongoDB 不会像使用允许 SQL 传递的 API 那样对相同类型的“脚本”注入攻击开放。

对于您的观点2。常识方法是仅将某些操作作为端点。比如query或者update,基本上都需要对客户端执行的操作进行认证。因此,您不会向 API 公开具有潜在危险的操作。

还需要考虑一般身份验证和角色。因此,您将只允许 API 执行其呈现的“角色”允许的操作。这可以为您提供更多保护,而不必在您的代码中检查这一点,或者至少只是从“未经授权”的操作中捕获错误。

最后是 3. 作为在提供的查询中检查 $where 运算符是否存在的可能替代方法(尽管您可以做的事情的限制得到每个版本都更好),您实际上可以使用--noscipting 选项在服务器上关闭它。

因此,您确实可以采取很多保护措施来帮助您避免“脚本注入”攻击,但一般来说,同样的危险是不存在的。

【讨论】:

  • 感谢您的完整性检查。幸运的是,对于我正在构建的应用程序,整个应用程序都是只读的,因此我不必担心角色和身份验证。不幸的是,我不能使用noscripting 标志。我将继续采用这种方法。
  • 可能应该在此处添加,即使您的应用程序代码从不处理update或类似操作,这也不是不是替代分配正确的authentication and roles。如果意图是只读,那么访问 API 的帐户应该只实现read 角色,或者按照Built-In Roles 中定义的应用程序只需要或谨慎的权限。
【解决方案2】:

一般来说,整个方法依赖于比这里第一个答案中提到的更多的东西,但关于安全性,最好的方法是偏执。

在 REST-API 中实现有关安全性的数据库查询是一项艰巨的工作,但我认为您已经有了一个良好的开端:
- 表名不暴露
- 查询被简化为最重要的参数,而不是完整的查询代码。

您仍应考虑和实施的内容:
- 任何字段名称(如 user)只有在预定义的允许字段数组中存在时才应在服务器端接受。
- 允许的字段可能因使用 REST-API、API-Key 或 API-Users 的用户组的用户而异。
- 你应该使用https 来避免man-in-the-middle-attacks。即使read-only 数据在到达客户端的途中被操纵也会造成损害。此外,https 的安装应在基准站点上进行测试,即https://www.htbridge.com/ssl/,只是证书并不安全。
- 对于某些操作,您可能需要一次性哈希以提高安全性。
- 每个 API 用户的请求数量可能受到限制,即每小时 20 或 100 个(尽可能低)。
- 应映射字段名称等关键字和orwhere 等 SQL,以便将它们与上述允许的表达式数组进行比较,或者在 JSON 中它们甚至可以不同并映射到服务器端到真正的查询表达式。所以在客户端它可能被称为user,但在数据库表中的服务器端,该字段被称为username,并且这个字段名不会暴露给客户端。
- 检查每个 API 用户是否允许查看请求的数据。例如,一些 API 用户可能只看到数据表的特殊用户组,但不是全部。
- 永远不要依赖任何客户端数据,验证和控制一切,即使在服务器端接受的选择在您的示例中也已经非常有限。
- 如果 where 子句在 JSON 中进行了精细翻译,您也可以允许它们,只是字符串很难验证。如果您像上面建议的那样映射所有字段以保持文档的完整性和正确性,即使 API 用户的字段名称可能与服务器端的实际名称不同,它只会做更多的工作。

【讨论】:

    猜你喜欢
    • 2021-03-14
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 2016-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多