提问人:shashantrika 提问时间:3/24/2021 最后编辑:shashantrika 更新时间:12/23/2021 访问量:1365
如何修复订单轨查询中的sql注入
How to fix sql injection in order rails query
问:
我是 ruby 的新手,并按照此博客修复了 sql 注入错误,但我的查询出现错误。
原始查询:
class Car < ActiveRecord::Base
...
has_one :Driver, lambda {
where(status: PASSENGER_STATUS, connected_number: [phone, mobile])
.order("FIELD (`classDummy`.`status`, #{PASSENGER_STATUS.join(', ')}")
}, class_name: :classDummy
而 , PASSENGER_STATUS 是 ( 在其他类中 )
PASSENGER_STATUS = [
'employed','temporary'
].freeze
我做了SQL注入修复
order("FIELD (`classDummy`.`status`, ? )", PASSENGER_STATUS.join(', '))
但这在执行查询时会引发异常。
我得到的异常:
ActiveRecord::StatementInvalid: Mysql2::Error:SQL语法有错误;查看与您的MySQL相对应的手册 服务器版本,以便在 '?,
答:
1赞
Jaffa
3/24/2021
#1
您阅读的博客是关于处理用户输入的,在这种情况下,防止 sql 注入非常重要。
在:
order("FIELD (`classDummy`.`status`, #{PASSENGER_STATUS.join(', ')})")
你是 SQL 查询中的注入代码,但它是你控制的代码,并且确切地知道它是什么,因此没有 SQL 注入的风险。
现在关于您的问题,在生成查询时不会替换参数,它根本无法像 .order
?
where
换句话说:使用你之前使用的代码,它运行良好,不受SQL注入的影响(只要你控制什么)PASSENGER_STATUS
检查日志以查看发送到服务器的 SQL 查询,您将更好地了解发生了什么
评论
0赞
shashantrika
3/25/2021
谢谢你的回答。我将尝试更改我的查询。
4赞
spickermann
3/25/2021
#2
正如 Geoffroy 已经指出的那样,在您的特定示例中,不存在 SQL 注入的风险,因为输入数据在您的控制之下。
但是,尽管如此,你仍然可以在 Rails Docs 中找到sanitize_sql_for_order
。文档中的示例与您的用例完全匹配:
sanitize_sql_for_order(condition)
接受 SQL 条件的数组或字符串,并将它们清理为 ORDER 子句的有效 SQL 片段。
sanitize_sql_for_order(["field(id, ?)", [1,3,2]]) # => "field(id, 1,3,2)" sanitize_sql_for_order("id ASC") # => "id ASC"
使用这种方法,你可以像这样编写你的关联:
has_one :Driver, lambda {
where(status: PASSENGER_STATUS, connected_number: [phone, mobile])
.order(sanitize_sql_for_order(["FIELD(`classDummy`.`status`, ?)", PASSENGER_STATUS])
}, class_name: :classDummy
评论