【问题标题】:Rails ActiveRecord: How to use bind variables with double quotes on jsonbRails ActiveRecord:如何在 jsonb 上使用带双引号的绑定变量
【发布时间】:2018-03-08 14:51:30
【问题描述】:

我有一个 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' }]"

这是无效的

我尝试了其他一些方法,但我想要的是绑定变量评估为带双引号的字符串:

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

或者其他解决方案 - 除了让刹车员跳过文件。

【问题讨论】:

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


    【解决方案1】:

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

    Rails 允许您这样做并在单引号字符串中替换单引号字符串这一事实表明 Rails 未能(像往常一样)理解 SQL 规则。

    但是您可以将参数占位符与其他字符串一起放在表达式中。我不是一个普通的 PostgreSQL 用户,但我假设你可以将字符串连接在一起形成一个完整的 JSON 文字:

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

    如果您参数化整个 JSON 值,您可能会发现它会使您的代码更加清晰。使用%Q() 避免需要反斜杠字面双引号。

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

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

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

    【讨论】:

    • 当然,谢谢。我从来没有想过让 JSON 成为绑定变量。完美。
    • 优秀的答案。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-02
    • 2023-01-08
    • 2021-11-23
    • 1970-01-01
    相关资源
    最近更新 更多