通过find,sql或where安全查询

时间:2012-10-31 21:31:56

标签: mysql ruby ruby-on-rails-3 activerecord

我想在某个列表query_list中找到所有具有公共或内部名称的小部件。我能做到

# Consider query_list = ["a","b","c"]
qlist = '(' + query_list.join(",") + ')'
# this makes 
widgets = Widget.find_by_sql("SELECT * FROM widgets 
     WHERE common_name IN #{qlist} OR internal_name IN #{qlist}")

现在我有几个问题:

  1. 上述find_by_sql对SQL注入攻击是否安全?似乎可以在query_list中放入一些危险的东西。
    • .find_by_sql(["SELECT * FROM widgets WHERE common_name IN ? OR internal_name IN ?", ["a","b","c"], ["a","b","c"] ])
    • 怎么样?
    • 如果不安全,我们可以安全吗?
  2. 如果我不需要,我不想写原始的SQL。我知道我们可以在AND中写find个条件,就像.find(:conditions=>{:internal_name => ['a','b','c'], :common_name => ['a','b','c']})一样。我们还可以使用find?
  3. 编写OR条件
  4. 使用where怎么样?这与使用find
  5. 有何不同?

1 个答案:

答案 0 :(得分:0)

带有占位符的版本可以安全地防止SQL注入,只要您不介意用户可以选择任意小部件,我认为您不会这样做。根据您拥有的Rails版本,您可以避免使用链接编写原始SQL;见Ruby on Rails 3 howto make 'OR' condition

请注意,如果列表为空,或者[nil],您的代码按原样或使用占位符会导致数据库错误,因此最好在进行查询之前测试query_list.first是否存在。