使用“database/sql”时如何防止 Go 中的 SQL 注入攻击?

Posted

技术标签:

【中文标题】使用“database/sql”时如何防止 Go 中的 SQL 注入攻击?【英文标题】:How can I prevent SQL injection attacks in Go while using "database/sql"? 【发布时间】:2014-12-08 07:58:50 【问题描述】:

构建我的第一个网络应用程序并希望更好地了解 SQL 注入 (https://github.com/astaxie/build-web-application-with-golang/blob/master/en/eBook/09.4.md)。

始终使用“数据库/sql”库和使用“?”构造查询,我可以获得多少针对 SQL 注入的保护而不是连接字符串?在这种情况下,我还需要担心什么样的 SQL 注入攻击?

【问题讨论】:

【参考方案1】:

只要您使用Prepare 或Query,您就是安全的。

// this is safe
db.Query("SELECT name FROM users WHERE age=?", req.FormValue("age"))
// this allows sql injection.
db.Query("SELECT name FROM users WHERE age=" + req.FormValue("age"))

【讨论】:

Exec 也允许在不使用 Prepare 的情况下绑定值。安全吗,我的猜测是它隐含了 Prepare 语句,但我没有查看代码 有没有办法让fmt.Sprintf安全。 @Entei 不是真的,除非您手动处理每个参数,否则没有理由不使用准备好的查询。 @OneOfOne 只是想知道是否可以使用字符串处理的 printf 样式。谢谢。 @OneOfOne 我不是数据库专家,我在 go posgres /lib/pq 中发现了这个问题讨论。他们在哪里讨论即使使用 Query 也存在一些漏洞? github.com/lib/pq/issues/248【参考方案2】:

我同意@Oneonone 的回答。

如果您要检索数据,请执行以下操作:

db.Query("SELECT name FROM users WHERE age=?", req.FormValue("age"))

如果您必须使用相同的查询安全地插入大量数据,这就是 Prepare 派上用场的地方。你可以这样做:

tx, err := db.Begin()
if err != nil 
    return nil,err

stmt, err := tx.Prepare("INSERT INTO users VALUES (?, ?)")
if err != nil 
    tx.Rollback()
    return nil,err

defer 
for i := 0; i < 10; i++ 
    _, err = stmt.Exec(i, "dummy")
    if err != nil 
        tx.Rollback()
        return nil,err
    

err = tx.Commit()
if err != nil 
    stmt.Close()
    tx.Rollback()
    return nil,err

stmt.Close()
return someValue, nil

参考:https://***.com/a/46476451/5466534

【讨论】:

以上是关于使用“database/sql”时如何防止 Go 中的 SQL 注入攻击?的主要内容,如果未能解决你的问题,请参考以下文章

Go语言操作MySQL

Go语言操作MySQL

golang 碎片整理之MySQL

Go操作MySQL

go database/sql sql-driver/mysql 操作

Go 操作 Mysql