在使用"数据库/ SQL"时如何防止Go中的SQL注入攻击?

这可以解决单值字段问题,因为您可以删除引号,但是我不能过滤JSON / JSONB字段,就像下面这样,因为$1被视为字符串:

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

以下方法可以工作,但是很容易发生SQL注入:

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

我该如何解决?

如何使用jsonb_*函数构建此json [{"foo": $1}]? 尝试了以下方法,但未成功:

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

这是您要找的东西吗?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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-s评论也有效。
  • 很高兴您能够结识所需的朋友。