【问题标题】:How to prevent SQL Injection in PostgreSQL JSON/JSONB field?如何防止 PostgreSQL JSON/JSONB 字段中的 SQL 注入?
【发布时间】:2023-03-18 21:40:01
【问题描述】:

How can I prevent SQL injection attacks in Go while using "database/sql"?

这解决了单值字段问题,因为您可以删除引号,但我无法过滤 JSON/JSONB 字段,如下所示,因为 $1 被视为字符串:

`SELECT * FROM foo WHERE bar @> '{"baz": "$1"}'`

以下方法可行,但容易发生 SQL 注入:

`SELECT * FROM foo WHERE bar @> '{"baz": "` + "qux" + `"}'`

我该如何解决这个问题?


在@mkopriva 发表评论后编辑:

如何使用 jsonb_* 函数构建这个 json [{"foo": $1}]?尝试以下但没有成功:

jsonb_build_array(0, jsonb_build_object('foo', $1::text))::jsonb

没有 sql 错误。过滤器只是不起作用。有一种方法可以检查构建的 sql 吗?我正在使用 database/sql 原生库。

【问题讨论】:

  • 通过使用json_build_object/jsonb_build_object 和类似的函数而不是从字符串构造json。例如。 ... bar @> json_build_object("bar", $1)
  • Go 中没有准备好的语句吗?这才是避免SQL注入的王道。
  • 去掉jsonb_build_array开头的0,;你正在创建[0, {"foo": …}]。此外,无需将jsonb_build_array 转换为jsonb

标签: postgresql go sql-injection


【解决方案1】:

这是你要找的吗?

type MyStruct struct {
    Baz string
}

func main() {
    db, err := sql.Open("postgres", "postgres://...")
    if err != nil {
        log.Panic(err)
    }

    s := MyStruct{
        Baz: "qux",
    }

    val, _ := json.Marshal(s)
    if err != nil {
        log.Panic(err)
    }

    if _, err := db.Exec("SELECT * FROM foo WHERE bar @> ?", val); err != nil {
        log.Panic(err)
    }
}

附带说明,Exec 不用于检索(尽管我为您保留了它,因此解决方案与您的示例相匹配)。查看db.Query(这里的精彩教程:http://go-database-sql.org/retrieving.html

【讨论】:

  • 我不得不稍微调整一下,并放置一个 json 标记来格式化结构中的键,但它起作用了。谢谢。 @Ry- 在问题中的评论也有效。
  • 很高兴你能得到你需要的朋友。
猜你喜欢
  • 1970-01-01
  • 2021-01-18
  • 1970-01-01
  • 1970-01-01
  • 2015-09-07
  • 2017-11-30
  • 2011-09-10
  • 2019-10-24
  • 1970-01-01
相关资源
最近更新 更多