从sql注入中保护select语句

时间:2015-10-27 08:45:03

标签: ruby-on-rails sql-injection strong-parameters

我最近偶然发现了api的一部分,用户可以在其中查询特定字段:

api/models?only=id,name

它是这样实现的:

@model = Model.select params[:only]

对于这一行我有一种安静的不好的感觉,如果有可能将sql注入代码的这一部分......我就试过了......

经过一番思考后我们想出了这个

@model = Model.select params[:only].split(',').map(&:to_sym)

这实际上可以防止注射。但这足以保护这部分API吗?

在这种情况下是否可以使用强参数?

query_params.require(:only).permit(:id,:name)

不起作用,因为传递的字段是字符串,并且没有方法permit

2 个答案:

答案 0 :(得分:2)

实际上,控制器不应该使用模型的实现细节。事实上,SQL的select中的值是以逗号分隔的,并且您的API按原样接受它是一个“巧合”,首先应该不依赖它。

我将向您介绍您可能会发现有用的工具,以便撰写您的解决方案。

# Array#&, set intersection
[1, 2, 3] & [2, 4, 1] # => [1, 2]

# Model.attributes
Model.attributes #=> ['id', 'name', ...]
# You can filter down the resulting array to produce a whitelist of columns

# Splat the array into the argument list
Model.select(*params[:only].split(',') & Model::SELECT_WHITELIST)
# ...the constant above has to be defined inside the model, obviously.

答案 1 :(得分:1)

您可以使用ActiveRecord::Base.sanitize

Model.select Model.sanitize(params[:only])