如何编写 sa"f"e Active Record 查询
Posted
技术标签:
【中文标题】如何编写 sa"f"e Active Record 查询【英文标题】:How to write sa"f"e Active Record queries 【发布时间】:2019-02-08 04:29:45 【问题描述】:我尝试在 Rails 中创建一个 API,该 API 可以动态调用以返回不同时间段内数据的最小值/最大值/平均值。 我有一些这样的范围:
scope :span, ->(span) group("date_round_down(device_time, '#span')::timestamp without time zone")
scope :func, ->(func) calculate("#func", 'point_data_val')
但是 group 方法不允许我做 params and ?像 'where' 这样的替换。
有没有一种安全的方法可以在 Rails 中将参数放入 SQL 字符串的中间?
【问题讨论】:
这对于.where
也不起作用,因为占位符已转义,因此它不能用作列名。以.where('? = 1', 'id')
为例。我会考虑改用白名单并用它来构造 SQL 字符串。
你选择了错误的方法,scope
返回一个值数组,尝试一个简单的方法定义。
实际上范围只是声明类方法@Зелёный的语法糖。你可以返回任何你想要的东西,例如scope :foo, -> "bar"
。当然,这样做会很愚蠢。它通常用于返回ActiveRecord::Relation
对象而不是数组。
【参考方案1】:
我能想到的唯一“安全”方法是通过白名单传递用户输入,例如可以通过.column_names
获取的列名或用户可以在查询。
直接将用户输入插入到查询中会使您容易受到 SQL 注入攻击,并且正常的清理对于这种相当特殊的情况是不可用的,因为它用于绑定和清理值 - 而不是列名或 SQL 关键字,这将是危险的从框架 POV 来看相当愚蠢。
【讨论】:
以上是关于如何编写 sa"f"e Active Record 查询的主要内容,如果未能解决你的问题,请参考以下文章
SVN 错误“禁止访问 '/svn/myservice/!svn/act/d99e498e-9a8d-374c-a3e4-fde21198bfa2'”