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

从始终使用'database / sql'库和使用'构造查询可以得到多少保护? 而不是容纳字符串? 在这种情况下,我仍然需要担心哪种SQL注入攻击?


只要您使用"准备"或"查询",就可以保证安全。

1
2
3
4
// 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样式。 谢谢。
  • db.Exec是否同样适用? 例如:db.Exec("DELETE from books where pk = ?", r.FormValue("pk"))
  • 那在golang呢? stackoverflow.com/questions/134099/
  • @AnikHasibul我不是100%肯定,但是Go通常处理这种事情比php要好得多。
  • @OneOfOne我不是数据库专家,我在posgres / lib / pq中找到了此问题的讨论。 他们在哪里讨论,甚至使用Query都存在一些漏洞? github.com/lib/pq/issues/248

我同意@Oneonone的回答。

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

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

如果您必须使用相同的查询安全地插入大量数据,这是Prepare方便的地方。 您可以执行以下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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://stackoverflow.com/a/46476451/5466534