Go语言如何防范 SQL注入、CSRF、XSS攻击
以下是一些示例代码,演示如何在Go应用程序中防范这些攻击:
防范 SQL 注入:
使用参数化查询或预处理语句,而不是直接拼接 SQL 字符串。
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/go-sql-driver/mysql"
)
func getUser(db *sql.DB, username string) (string, error) {
// 使用参数化查询
query := "SELECT name FROM users WHERE username = ?"
row := db.QueryRow(query, username)
var name string
err := row.Scan(&name)
if err != nil {
return "", err
}
return name, nil
}
func main() {
db, err := sql.Open("mysql", "user:password@tcp(localhost:3306)/database")
if err != nil {
log.Fatal(err)
}
defer db.Close()
username := "john'; DROP TABLE users; --"
name, err := getUser(db, username)
if err != nil {
log.Fatal(err)
}
fmt.Println("User's name:", name)
}
在上述例子中,getUser 函数使用参数化查询而不是直接插入用户输入到 SQL 查询中。
防范 CSRF 攻击:
使用随机生成的 token,并将其嵌入到表单中,验证提交的表单中的 token 是否与服务器端生成的一致。
package main
import (
"crypto/rand"
"encoding/base64"
"fmt"
"html/template"
"net/http"
)
var csrfToken string
func generateCSRFToken() string {
token := make([]byte, 32)
rand.Read(token)
return base64.StdEncoding.EncodeToString(token)
}
func indexHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
token := r.FormValue("csrfToken")
if token != csrfToken {
http.Error(w, "CSRF token mismatch", http.StatusForbidden)
return
}
// 处理表单提交
fmt.Fprintln(w, "Form submitted successfully!")
return
}
// 生成 CSRF token
csrfToken = generateCSRFToken()
// 将 token 嵌入到 HTML 模板中
tmpl, err := template.New("index").Parse(`
<html>
<body>
<form method="post">
<input type="text" name="username" placeholder="Username">
<input type="password" name="password" placeholder="Password">
<input type="hidden" name="csrfToken" value="{{.CSRFToken}}">
<button type="submit">Login</button>
</form>
</body>
</html>
`)
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
// 渲染 HTML 模板
data := struct{ CSRFToken string }{CSRFToken: csrfToken}
tmpl.Execute(w, data)
}
func main() {
http.HandleFunc("/", indexHandler)
http.ListenAndServe(":8080", nil)
}
在上述例子中,generateCSRFToken 函数生成随机的 CSRF token,并将其嵌入到表单中。在处理表单提交时,验证提交的 token 是否与服务器端生成的一致。
## 防范 XSS 攻击:
>使用 html/template 包来对输出进行 HTML 转义。
package main
import (
"html/template"
"net/http"
)
func mainHandler(w http.ResponseWriter, r *http.Request) {
// 模拟从用户输入中获取的数据
userInput := <script> alert('XSS attack!');</script>
// 使用 html/template 包对输出进行转义
tmpl, err := template.New("index").Parse(`
<html>
<body>
<p>User Input: {{.UserInput}}</p>
</body>
</html>
`)
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
// 渲染 HTML 模板
data := struct{ UserInput string }{UserInput: userInput}
tmpl.Execute(w, data)
}
func main() {
http.HandleFunc("/", mainHandler)
http.ListenAndServe(":8080", nil)
}
在上述例子中,html/template 包会对 UserInput 进行 HTML 转义,防止其中包含的脚本被执行。
请注意,这些仅仅是一些基本的示例代码,实际情况可能会根据具体的应用场景和需求而有所不同。安全性是一个持续的过程,需要结合具体的应用场景和最新的安全标准来实施