我正在制作自己的 API,我想知道:如何保护收到的参数?
示例:
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 进行利用怎么办? 你如何处理这个?
您问题中的示例均会自动防止 SQL 注入。
来自官方Rails Guides的相关引用:
7.2.1 简介
SQL注入攻击旨在通过操纵Web应用程序参数来影响数据库查询。 SQL 注入攻击的一个常见目标是绕过授权。另一个目标是执行数据操作或读取任意数据。以下是如何不在查询中使用用户输入数据的示例:
Project.where("name = '#{params[:name]}'")
然后在同一个文档中:
7.2.4 对策
Ruby on Rails 有一个针对特殊 SQL 字符的内置过滤器,它将转义
、'
、NULL 字符和换行符。使用"
或Model.find(id)
会自动应用此对策。但在 SQL 片段中,尤其是在条件片段 (Model.find_by_some thing(something)
)、where("...")
或connection.execute()
方法中,必须手动应用。Model.find_by_sql()
您可以使用位置处理程序来清理受污染的字符串,而不是传递字符串,如下所示:
Model.where("zip_code = ? AND quantity >= ?", entered_zip_code, entered_quantity).first
第一个参数是带有问号的SQL片段。第二个和第三个参数将用变量的值替换问号。
您还可以使用命名处理程序,这些值将从使用的哈希中获取:
values = { zip: entered_zip_code, qty: entered_quantity } Model.where("zip_code = :zip AND quantity >= :qty", values).first
此外,您可以拆分和链接适用于您的用例的条件:
Model.where(zip_code: entered_zip_code).where("quantity >= ?", entered_quantity).first
在大多数情况下,Rails 负责 SQL 注入。 因此,您应该避免将字符串作为参数传递给 Active Records 方法。避免这种情况:
Car.where("color = '#{params[:color]'")
请使用数组或哈希:
car = Car.where(color: params[:color])
car = Car.where(["color = ?", params[:color])
通过这样做,Active Records 将自动转义不需要的字符,从而防止 SQL 注入。
有关更多信息,请参阅 Rails 文档:https://guides.rubyonrails.org/security.html#sql-injection-countermeasures
在 @spickermann 报告了一个重大错误后,我更新了此回复。