构建我的第一个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