2

我不确定我是否知道在活动记录中编写此 sql 查询的最佳方法,而无需完全手动编写。本质上,我想编写这两个查询的组合。

这个查询本质上是我试图重新创建的连接。我想确保返回的任何条目都只是那些将 image_path_processing 标志设置为 false 的图像。

@entries = ContestEntry.joins(:entry_images).where(contest_id: @contest.id, entry_images: {
        image_path_processing: false
        }).limit(10)

但是,我正在编写的查询遇到的问题是我需要包含来自 url 的参数,并且我不确定上述语法是否正确删除了 sql_injection

这是我试图添加条件连接的内容。

@entries = ContestEntry.where("contest_id = ? and created_at > ?",
      params[:contest_id], Time.at(params[:after].to_i + 1))
4

3 回答 3

2

你能试试这个吗?

@entries = ContestEntry.joins(:entry_images).
                        where(contest_id: params[:contest_id],
                              entry_images: { image_path_processing: false }).
                        where('contest_entries.created_at > ?', Time.at(params[:after].to_i+1)).
                        limit(10)
于 2013-03-06T18:51:53.377 回答
1

首先,阅读本文档: http: //guides.rubyonrails.org/security.html#sql-injection

过去,主要支持的语法是

ContestEntry.where("contest_id = ?", params[:contest_id])

但现在你也可以使用更简单和更红宝石的

ContestEntry.where(:contest_id => params[:contest_id])

这两种方法都将通过 sql sanitizer 传递参数,以防止 sql-injection 攻击,如文档中所述。

还有几点:

  1. 我不知道如何为除相等之外的任何东西实现后一种语法。
  2. 您最近听到的有关 sql 注入的问题不适用于您正在使用的语法。它们适用于动态查找器。

最后,你不应该相信我的话。ruby 开发人员给我的最好的建议之一是“使用 irb 来学习 ruby​​”。如果您对某项工作的原理有疑问,请加载 irb 并对其进行测试。在您的情况下,您正在实施 rails,因此您可以使用完整的控制台。

sql_injection_params = "anything' OR 'x'='x"
# This string variant tells active record to use sql as is 
Model.where("name = '#{sql_injection_params}'").to_sql # bad
# This array variant tells active record to sanitize
Model.where('name = ?', sql_injection_params).to_sql # good
# This hash variant tells active record to sanitize
Model.where(:name => sql_injection_params).to_sql # good

to_sql调用将显示基于您的查询构建的原始 SQL 活动记录。只需更改上面的示例以使用您的数据,您就应该更好地了解 Rails 在幕后所做的事情。

于 2013-03-06T19:05:21.233 回答
0
@entries = ContestEntry.where("contest_id = ? and created_at > ?",
      params[:contest_id], Time.at(params[:after].to_i + 1))

似乎是避免用户输入结果中的 sql 注入的完美方法......

于 2013-03-06T18:39:13.690 回答