【发布时间】:2021-03-26 17:35:18
【问题描述】:
我正在尝试参数化我的 postgresql 查询,以防止我的 ruby on rails 应用程序中的 SQL 注入。 SQL 查询将根据输入对我的表中的不同值求和。
这是我的函数的简化版本:
def self.calculate_value(value)
calculated_value = ""
if value == "quantity"
calculated_value = "COALESCE(sum(amount), 0)"
elsif value == "retail"
calculated_value = "COALESCE(sum(amount * price), 0)"
elsif value == "wholesale"
calculated_value = "COALESCE(sum(amount * cost), 0)"
end
query = <<-SQL
select CAST(? AS DOUBLE PRECISION) as ? from table1
SQL
return Table1.find_by_sql([query, calculated_value, value])
end
如果我调用calculate_value("retail"),它将执行如下查询:
select location, CAST('COALESCE(sum(amount * price), 0)' AS DOUBLE PRECISION) as 'retail' from table1 group by location
这会导致错误。我希望它在没有这样的引号的情况下执行:
select location, CAST(COALESCE(sum(amount * price), 0) AS DOUBLE PRECISION) as retail from table1 group by location
我知道添加引号是防止 sql 注入的原因,但在这种情况下我将如何防止它呢?处理这种情况的最佳方法是什么?
注意:这是我将要编写的查询的简化版本,我想使用 find_by_sql。
【问题讨论】:
-
标识符需要双引号,单引号是或值。
-
别名不能是参数。而且,它必须是一个常数——动态输出结构不是确定性的。建议 - 创建 3 个单独的最终非参数化查询文本,并根据提供的参数选择其中一个。