英文:
How can I prevent SQL injection attacks in Go while using "database/sql"?
问题
构建我的第一个 Web 应用程序,并希望更好地理解 SQL 注入(https://github.com/astaxie/build-web-application-with-golang/blob/master/en/eBook/09.4.md)。
如果我始终使用 'database/sql' 库并使用 '?' 构建查询,而不是连接字符串,那么我能获得多少防止 SQL 注入的保护?在这种情况下,我仍然需要担心哪些类型的 SQL 注入攻击?
英文:
Building my first web-app and want to understand SQL injection better (https://github.com/astaxie/build-web-application-with-golang/blob/master/en/eBook/09.4.md).
How much protection against SQL injection do I get from just always using the 'database/sql' library and constructing queries using '?' instead of concatting strings? What kind of SQL injection attacks will I still have to worry about in that case?
答案1
得分: 46
// 这是安全的
db.Query("SELECT name FROM users WHERE age=?", req.FormValue("age"))
// 这样会导致 SQL 注入。
db.Query("SELECT name FROM users WHERE age=" + req.FormValue("age"))
英文:
As long as you're using Prepare or Query, you're safe.
// 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"))
答案2
得分: 7
我同意@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 stmt.Close()
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
英文:
I agree with @Oneonone's answer.
If you are retrieving data, do something like:
db.Query("SELECT name FROM users WHERE age=?", req.FormValue("age"))
If you have to insert a lot of data safely, using the same query, this is where Prepare comes handy. you can do something like this:
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
答案3
得分: 0
如果准备好的语句不够用,你可以使用查询构建器。
我创建了 hotcoal 包,它可以帮助你保护手工编写的 SQL 免受注入攻击。它提供了一个简洁的 API,你可以与任何 SQL 库一起使用。
英文:
If prepared statements are not enough, you can use a query builder.
I created the hotcoal package, which helps you secure your handcrafted SQL against injection. It provides a minimal API and you can use it with any SQL library.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论