Rails ActiveRecord:如何在jsonb上使用带双引号的绑定变量

时间:2018-03-08 14:51:31

标签: ruby-on-rails postgresql sql-injection jsonb

我有一个postgres jsonb查询如下:

Blog.where("upload_data @> '[ { \"name\": \"#{name}\" }]'")

哪个有效,但打破了构建,因为优秀的制动员指出了可能的SQL注入风险。如果我使用绑定变量:

Blog.where("upload_data @> '[ { \"name\": ? }]'", name)

它创建一个sql查询,如:

WHERE upload_data @> '[ { "name": 'name' }]'

请注意单引号 - 这是一个无效的查询

如果我使用单引号,我会得到:

WHERE upload_data @> "[ { 'name': 'name' }]"

无效

我尝试过其他一些东西,但我想要的是将bind变量计算为带双引号的字符串:

WHERE upload_data @> '[ { "name": "name" }]'

或者不同的解决方案 - 除了让刹车手跳过文件。

1 个答案:

答案 0 :(得分:2)

您不能将参数占位符放在带引号的字符串中。

Rails允许您执行此操作并在单引号字符串中替换单引号字符串这一事实表明Rails(通常)无法理解SQL规则。

但是您可以将参数占位符放在表达式中,并使用其他字符串。我不是常规的PostgreSQL用户,但我认为你可以将字符串连接在一起形成一个完整的JSON文字:

PhoneGap Build

如果参数化整个JSON值,您可能会发现它使代码更加清晰。使用Blog.where("upload_data @> '[ { \"name\": \"' || ? || '\"}]'", name) 以避免需要反斜杠文字双引号。

%Q()

或者为了确保生成有效的JSON,我将表达式放在Ruby语法中,然后转换为JSON:

Blog.where("upload_data @> ?", %Q([ { "name": "#{name}" } ]))