Waffle 簡介:Go 應用程式的應用程式內 WAF
介紹
Web 應用程式防火牆 (WAF) 長期以來一直是保護 Web 應用程式的標準安全解決方案。 AWS WAF 和 Cloudflare WAF 等基於雲端的 WAF 由於易於實施而特別受歡迎。然而,它們也面臨一些挑戰:
- 對應用程式上下文的了解有限
- 誤報率高
- 受限的自訂邏輯實作
為了應對這些挑戰,一種稱為應用內 WAF 或 RASP(運行時應用程式自我保護)的新方法正在引起人們的注意。
在這篇文章中,我將介紹 Waffle,一個用於將應用程式內 WAF 功能整合到 Go Web 應用程式中的程式庫。
- https://sitebatch.github.io/waffle-website
- https://github.com/sitebatch/waffle-go
什麼是應用內 WAF/RASP?
應用程式內 WAF/RASP 並不是要取代現有的雲端 WAF,而是透過將 WAF 功能直接嵌入到您的應用程式中來補充它們,以增強保護。
它可以處理常見的 Web 應用程式攻擊,例如 SQL 注入和 XSS,以及應用程式業務邏輯攻擊,例如撞庫和暴力嘗試。
主要優勢是透過完整的請求上下文感知來準確檢測和預防。
考慮這個用於建立部落格文章的 HTTP 請求:
POST /blog/post HTTP/1.1 ... { "title": "What is SQL ?" "body": "SQL example code: `SELECT * FROM users` ..." }
如果您的應用程式使用佔位符來安全地建構 SQL 語句,則 SQL 注入是不可能的。但是,依賴模式匹配的基於雲端的 WAF 會阻止此請求,因為它包含可疑的類似 SQL 的模式(字串 SELECT * FROM 會引發 SQL 注入問題)。
開發人員經常發現自己需要繁瑣地調整參數、端點或 WAF 規則來減少這些誤報。好麻煩的任務啊!
相較之下,應用內 WAF / RASP 可以理解請求上下文。它可以識別何時未使用佔位符,並且僅在「實際上可能發生 SQL 注入」時阻止攻擊。這種情境感知方法可以減少誤報,甚至可以幫助緩解零日漏洞。
在 Go 應用程式中使用 Waffle 實作應用程式內 WAF/RASP
Waffle 是一個在 Go Web 應用程式中啟用應用程式內 WAF / RASP 功能的函式庫。
讓我們看看如何將 Waffle 整合到您的應用程式中以及它如何防止攻擊。
應用範例
雖然此範例使用標準函式庫的 net/http,但 Waffle 也支援其他函式庫,例如 Gin 和 GORM。
有關更多詳細信息,請查看支援的庫文檔。
以下應用程式在 /login 端點中存在 SQL 注入漏洞:
POST /blog/post HTTP/1.1 ... { "title": "What is SQL ?" "body": "SQL example code: `SELECT * FROM users` ..." }
package main import ( "context" "database/sql" "fmt" "net/http" _ "github.com/mattn/go-sqlite3" ) var database *sql.DB func init() { setupDB() } func newHTTPHandler() http.Handler { mux := http.NewServeMux() mux.Handle("/login", http.HandlerFunc(loginController)) return mux } func main() { srv := &http.Server{ Addr: ":8000", Handler: newHTTPHandler(), } srv.ListenAndServe() } func loginController(w http.ResponseWriter, r *http.Request) { email := r.FormValue("email") password := r.FormValue("password") if err := login(r.Context(), email, password); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Write([]byte("Login success")) } func login(ctx context.Context, email, password string) error { // ⚠️ SQL INJECTION VULNERABILITY rows, err := database.QueryContext(ctx, fmt.Sprintf("SELECT * FROM users WHERE email = '%s' AND password = '%s'", email, password)) if err != nil { return err } defer rows.Close() if !rows.Next() { return fmt.Errorf("invalid email or password") } // do something return nil } func setupDB() { db, err := sql.Open("sqlite3", "file::memory:?cache=shared") if err != nil { panic(err) } if _, err := db.Exec("CREATE TABLE users(id int, email text, password text);"); err != nil { panic(err) } if _, err := db.Exec("INSERT INTO users(id, email, password) VALUES(1, 'user@example.com', 'password');"); err != nil { panic(err) } database = db }
整合Waffle防止SQL注入
讓我們整合Waffle來防止SQL注入:
$ go run . # SQL injection attack $ curl -i -X POST 'http://localhost:8000/login' \ --data "email=user@example.com' OR 1=1--&password=" HTTP/1.1 200 OK Date: Sun, 05 Jan 2025 10:32:50 GMT Content-Length: 13 Content-Type: text/plain; charset=utf-8 Login success
修改main.go如下:
$ go get github.com/sitebatch/waffle-go
變化很小:
package main import ( "context" "database/sql" "errors" "fmt" "net/http" "github.com/sitebatch/waffle-go" "github.com/sitebatch/waffle-go/action" waffleSQL "github.com/sitebatch/waffle-go/contrib/database/sql" waffleHTTP "github.com/sitebatch/waffle-go/contrib/net/http" _ "github.com/mattn/go-sqlite3" ) var database *sql.DB func init() { setupDB() } func newHTTPHandler() http.Handler { mux := http.NewServeMux() mux.Handle("/login", http.HandlerFunc(loginController)) handler := waffleHTTP.WafMiddleware(mux) return handler } func main() { srv := &http.Server{ Addr: ":8000", Handler: newHTTPHandler(), } // Start waffle with debug mode waffle.Start(waffle.WithDebug()) srv.ListenAndServe() } func loginController(w http.ResponseWriter, r *http.Request) { email := r.FormValue("email") password := r.FormValue("password") if err := login(r.Context(), email, password); err != nil { var actionErr *action.BlockError if errors.As(err, &actionErr) { return } http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Write([]byte("Login success")) } func login(ctx context.Context, email, password string) error { // ⚠️ SQL INJECTION VULNERABILITY rows, err := database.QueryContext(ctx, fmt.Sprintf("SELECT * FROM users WHERE email = '%s' AND password = '%s'", email, password)) if err != nil { return err } defer rows.Close() if !rows.Next() { return fmt.Errorf("invalid email or password") } // do something return nil } func setupDB() { db, err := waffleSQL.Open("sqlite3", "file::memory:?cache=shared") if err != nil { panic(err) } if _, err := db.Exec("CREATE TABLE users(id int, email text, password text);"); err != nil { panic(err) } if _, err := db.Exec("INSERT INTO users(id, email, password) VALUES(1, 'user@example.com', 'password');"); err != nil { panic(err) } database = db }
現在,當我們嘗試 SQL 注入攻擊時,Waffle 會阻止它:
diff --git a/main.go b/main.go index 90b8197..9fefb06 100644 --- a/main.go +++ b/main.go @@ -3,9 +3,15 @@ package main import ( "context" "database/sql" + "errors" "fmt" "net/http" + "github.com/sitebatch/waffle-go" + "github.com/sitebatch/waffle-go/action" + waffleSQL "github.com/sitebatch/waffle-go/contrib/database/sql" + waffleHTTP "github.com/sitebatch/waffle-go/contrib/net/http" + _ "github.com/mattn/go-sqlite3" ) @@ -19,7 +25,9 @@ func newHTTPHandler() http.Handler { mux := http.NewServeMux() mux.Handle("/login", http.HandlerFunc(loginController)) - return mux + handler := waffleHTTP.WafMiddleware(mux) + + return handler } func main() { @@ -28,6 +36,9 @@ func main() { Handler: newHTTPHandler(), } + // Start waffle with debug mode + waffle.Start(waffle.WithDebug()) + srv.ListenAndServe() } @@ -36,6 +47,11 @@ func loginController(w http.ResponseWriter, r *http.Request) { password := r.FormValue("password") if err := login(r.Context(), email, password); err != nil { + var actionErr *action.BlockError + if errors.As(err, &actionErr) { + return + } + http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -60,7 +76,7 @@ func login(ctx context.Context, email, password string) error { } func setupDB() { - db, err := sql.Open("sqlite3", "file::memory:?cache=shared") + db, err := waffleSQL.Open("sqlite3", "file::memory:?cache=shared") if err != nil { panic(err) }
此 HTML 是 waffle 預設回傳的錯誤訊息,如下所示:
如果使用佔位符:
使用佔位符時,Waffle 會辨識出不可能進行 SQL 注入,並且不會阻止要求:
$ curl -i -X POST 'http://localhost:8000/login' \ --data "email=user@example.com' OR 1=1--&password=" -i HTTP/1.1 403 Forbidden Date: Sun, 05 Jan 2025 10:38:22 GMT Content-Length: 1574 Content-Type: text/html; charset=utf-8 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Access Denied</title>
# Fix SQL injection vulnerability diff --git a/main.go b/main.go index 9fefb06..5b482f2 100644 --- a/main.go +++ b/main.go @@ -60,7 +60,7 @@ func loginController(w http.ResponseWriter, r *http.Request) { } func login(ctx context.Context, email, password string) error { - rows, err := database.QueryContext(ctx, fmt.Sprintf("SELECT * FROM users WHERE email = '%s' AND password = '%s'", email, password)) + rows, err := database.QueryContext(ctx, "SELECT * FROM users WHERE email = ? AND password = ?", email, password) if err != nil { return err }
請注意,即使在這種情況下,Waffle 仍然可以像基於雲端的 WAF 一樣檢測嘗試的 SQL 注入(儘管它不會阻止它):
# Waffle won't block the request since SQL injection isn't possible $ curl -i -X POST 'http://localhost:8000/login' \ --data "email=user@example.com' OR 1=1--&password=" HTTP/1.1 500 Internal Server Error Content-Type: text/plain; charset=utf-8 X-Content-Type-Options: nosniff Date: Sun, 05 Jan 2025 10:49:05 GMT Content-Length: 26 invalid email or password
Waffle 偵測與預防的攻擊
雖然我們已經示範了 SQL 注入預防,但 Waffle 可以偵測並防止各種攻擊:
- 已知安全掃描儀的偵察
- 目錄遍歷
- XSS
- SQL注入
- 敏感檔案存取
- SSRF
- 帳號接管
有關更多詳細信息,請查看規則列表文件。
規則持續更新,歡迎貢獻。
結論
透過將 Waffle 整合到您的應用程式中,您可以準確地偵測和預防攻擊。
特定於框架的實作指南和詳細使用說明,請參閱文件中的指南部分。
Waffle 正在積極開發中。我們歡迎回饋和貢獻。
- https://github.com/sitebatch/waffle-go
以上是Waffle 簡介:Go 應用程式的應用程式內 WAF的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Golang在性能和可擴展性方面優於Python。 1)Golang的編譯型特性和高效並發模型使其在高並發場景下表現出色。 2)Python作為解釋型語言,執行速度較慢,但通過工具如Cython可優化性能。

Golang在並發性上優於C ,而C 在原始速度上優於Golang。 1)Golang通過goroutine和channel實現高效並發,適合處理大量並發任務。 2)C 通過編譯器優化和標準庫,提供接近硬件的高性能,適合需要極致優化的應用。

goisidealforbeginnersandsubableforforcloudnetworkservicesduetoitssimplicity,效率和concurrencyFeatures.1)installgromtheofficialwebsitealwebsiteandverifywith'.2)

Golang適合快速開發和並發場景,C 適用於需要極致性能和低級控制的場景。 1)Golang通過垃圾回收和並發機制提升性能,適合高並發Web服務開發。 2)C 通過手動內存管理和編譯器優化達到極致性能,適用於嵌入式系統開發。

goimpactsdevelopmentpositationality throughspeed,效率和模擬性。 1)速度:gocompilesquicklyandrunseff,IdealforlargeProjects.2)效率:效率:ITScomprehenSevestAndardArdardArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdEcceSteral Depentencies,增強的Depleflovelmentimency.3)簡單性。

Golang和Python各有优势:Golang适合高性能和并发编程,Python适用于数据科学和Web开发。Golang以其并发模型和高效性能著称,Python则以简洁语法和丰富库生态系统著称。

Golang和C 在性能上的差異主要體現在內存管理、編譯優化和運行時效率等方面。 1)Golang的垃圾回收機制方便但可能影響性能,2)C 的手動內存管理和編譯器優化在遞歸計算中表現更為高效。

Golang和C 在性能競賽中的表現各有優勢:1)Golang適合高並發和快速開發,2)C 提供更高性能和細粒度控制。選擇應基於項目需求和團隊技術棧。
