Ruby on rails sql注入问题的复杂作用域
在我的Rails应用程序中,我的作用域如下所示:Ruby on rails sql注入问题的复杂作用域,ruby-on-rails,ruby,Ruby On Rails,Ruby,在我的Rails应用程序中,我的作用域如下所示: scope :organization_join, -> (organization_type) { organization_table_name = organization_type.underscore.pluralize joins("LEFT JOIN \"#{organization_table_name}\" ON \"#{organization_table_name}\".\"organi
scope :organization_join, -> (organization_type) {
organization_table_name = organization_type.underscore.pluralize
joins("LEFT JOIN \"#{organization_table_name}\"
ON \"#{organization_table_name}\".\"organization_id\" = \"survey_reports\".\"organization_id\" AND
\"survey_reports\".\"organization_type\" = '#{organization_type}'"
)
}
此作用域允许sql注入攻击。。。
为了确保sql注入的安全,重写此文件的最佳方法是什么?这里有两个问题:
- 您为转换为表名且未根据有效表名白名单进行测试的类型引入参数
- 您可以在查询中内联潜在用户数据
ORGANIZATION_TABLES = %w[
team
club
house
]
scope :organization_join, -> (organization_type) {
case (organization_type)
when *ORGANIZATION_TABLES
_table = organization_type.underscore.pluralize
joins(
"LEFT JOIN %s ON %s.%s = %s.%s",
_table,
_table, :organization_id,
:survey_reports, :organization_id,
).where(
survey_reports: { organization_type: organization_type }
)
else
raise "No idea what #{organization_type} is."
end
}
在这里,我将join子句的一部分切换为标准的where
,它允许使用内置转义函数。其次,因为这些列名或表名都不是保留字,所以不需要麻烦用引号将它们转义
如果您能简单地做到这一点,您可能会发现这完全是多余的:
scope :organization_join, -> (organization_type) {
includes(:survey_reports).where(survey_reports: { organization_type: organization_type })
}
如果您有一个适当的
和多个关系,这允许使用隐式连接进行急切加载。这是一个非常清晰的答案。