如何清理 Rails API 参数

问题描述 投票:0回答:2

我正在制作自己的 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 ruby-on-rails ruby api-design
2个回答
6
投票

您问题中的示例均会自动防止 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)
Model.find_by_some thing(something)
会自动应用此对策。但在 SQL 片段中,尤其是在条件片段 (
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

-1
投票

在大多数情况下,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 报告了一个重大错误后,我更新了此回复。

© www.soinside.com 2019 - 2024. All rights reserved.