是否可以使用 Mongoid 在 Rails 上对 Ruby 进行 nosql 注入?

Is nosql injection possible for Ruby on Rails with Mongoid?

我正在尝试调查是否可以使用 mongo 和 mongoid gems 在 Rails 上的 Ruby 上进行 nosql 注入。

我使用 Mongo::Client 包含 Mongoid::Document 的集合和模型完成了 Mongodb 的请求。

我试图传递一些命令字符,例如 ' " \ ; { },但已被清除。通过 GET search?title[$ne]=foo 的特征类似于 {"title"=>"{\"$ne\"=>\"foo\"}"},因此这里似乎没有任何问题。

如果我使用这个技术栈的普通方法,是否可以进行nosql注入?

这来自 mongdodb 文档

As a client program assembles a query in MongoDB, it builds a BSON object, not a string. Thus traditional SQL injection attacks are not a problem. More details and some nuances are covered below.

MongoDB represents queries as BSON objects. Typically client libraries provide a convenient, injection free, process to build these objects. Consider the following C++ example:

https://docs.mongodb.com/manual/faq/fundamentals/#how-does-mongodb-address-sql-or-query-injection

常见操作包括查询和 Mongoid 中的 inserts/updates 会清理它们的输入,因此大多数时候不需要担心 "nosql injection"。

但是,有一些方法可以将命令直接传递到数据库,在这些情况下,仔细考虑未过滤的用户输入是否最终会成为数据库命令很重要。例如,如果 Post 是一个 Mongoid 模型,可以 运行 以下命令在 MongoDB 服务器中创建一个无限循环:

Post.all.map_reduce('function(){while(true);}','function(){}').out(inline:1).count

另一个例子是驱动程序提供的Database#command方法运行任意数据库命令:http://api.mongodb.com/ruby/current/Mongo/Database.html#command-instance_method。如果应用程序将用户输入放入提供给此方法的参数中,这会产生 "nosql injection".

的可能性

另请注意,没有必要将意外的 command 传递给数据库 - 有时意外的 data 就足够了。例如,参见 https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS。假设 Post 模型有一个主体字段,从用户传递任意正则表达式可能会有问题:

# This might take a while
Post.where('body' => {'$regex' => '((a|a?|a*)*)*$'}).count

可能,但容易被忽视。

事实上,你很接近。
不信任来源不仅仅来自 GET 参数。
Mongoid 不会帮你做任何事情;在您的示例中,阻止成功利用的是这样一个事实,即在 RoR 中,您不能将 Hash 作为 GET 参数传递。

未过滤的参数可以来自 JSON,例如这个。

posts = PrivatePost.where({ owner_id: json_params[:owner_id] }).each.to_a

其中 json_params[:owner_id] 可能包含 { '$ne': 'the owner' },
这可能会 posts 泄露给其他人。

或者通过基于 POST 的 API:

扰乱操作范围
Post.where({ _id: json_params[:id] }).delete_all