例如:
- 我有一个Car模型,具有“brand”和“color”属性。
car = Car.where(color: params[:color])
# or
car = Car.find_by(brand: params[:brand])
# or writing
Car.first.update!(brand: params[:brand])
但是我非常担心如果有人试图利用SQL或XSS漏洞会怎么样? 你是如何处理这个问题的?
car = Car.where(color: params[:color])
# or
car = Car.find_by(brand: params[:brand])
# or writing
Car.first.update!(brand: params[:brand])
你问题中的示例已经自动受到了防止 SQL 注入攻击的保护。
以下是官方 Rails Guides 中相关的引用:
7.2.1 Introduction
SQL injection attacks aim at influencing database queries by manipulating web application parameters. A popular goal of SQL injection attacks is to bypass authorization. Another goal is to carry out data manipulation or reading arbitrary data. Here is an example of how not to use user input data in a query:
Project.where("name = '#{params[:name]}'")
然后在同一篇文档中:
7.2.4 Countermeasures
Ruby on Rails has a built-in filter for special SQL characters, which will escape
'
,"
, NULL character, and line breaks. UsingModel.find(id)
orModel.find_by_some thing(something)
automatically applies this countermeasure. But in SQL fragments, especially in conditions fragments (where("...")
), theconnection.execute()
orModel.find_by_sql()
methods, it has to be applied manually.Instead of passing a string, you can use positional handlers to sanitize tainted strings like this:
Model.where("zip_code = ? AND quantity >= ?", entered_zip_code, entered_quantity).first
The first parameter is a SQL fragment with question marks. The second and third parameter will replace the question marks with the value of the variables.
You can also use named handlers, the values will be taken from the hash used:
values = { zip: entered_zip_code, qty: entered_quantity } Model.where("zip_code = :zip AND quantity >= :qty", values).first
Additionally, you can split and chain conditionals valid for your use case:
Model.where(zip_code: entered_zip_code).where("quantity >= ?", entered_quantity).first
Car.where("color = '#{params[:color]'")
car = Car.where(color: params[:color])
car = Car.where(["color = ?", params[:color])
更多信息,请参阅Rails文档:https://guides.rubyonrails.org/security.html#sql-injection-countermeasures
car = Car.where(color: params[:color])
在 Rails 中更为惯用,可以防止 SQL 注入。请注意 where
和 find_by
是非常不同的方法,where
返回可链式操作的关系集合,而 find_by
则返回单个记录。 - spickermannfind
和where
之间的差异,谢谢! :) - NaughtyDestiny