Go1.25 新特性:引入 WaitGroup.Go 和 CSRF 等方法,提升安全性!
今天帶了 2 個日常可能會接觸到的新版本小特性,開發經常用到。對大家應該會有所幫助。
sync:新增 WaitGroup.Go
問題背景
Go 這一門編程語言最大的特性之一就是:并發。非常好寫并發,剛入門都能寫。
而在傳統 Go 并發代碼中,需要使用 sync.WaitGroup 協調多個 goroutine 去編寫代碼。
例子如下:
var wg sync.WaitGroup
for i := 1; i <= 5; i++ {
i := i
wg.Add(1)
go func() {
defer wg.Done()
work(i)
}()
}
wg.Wait()這段代碼看似簡單,但也容易出錯。
例如:wg.Add 必須在啟動 goroutine 前調用、必須調用 wg.Done(),同時 Go1.22 之前還存在 for 循環變量閉包等常見 “陷阱”。
新提案
因此為了優化這個場景,社區里的同學 @Olivier Mengué 提出了《sync: add WaitGroup.Go[1]》的新提案:
圖片
提案本身并不復雜。核心的訴求就是增加一個新的方法 wg.Go:
func (wg *WaitGroup) Go(task func()) {
wg.Add(1)
go func() {
defer wg.Done()
task()
}()
}借助新的方案,可以將以往的方法簡化成:
var wg WaitGroup
for i := 1; i <= 5; i++ {
i := i // avoid loopvar footgun for go < 1.22
wg.Go(func() {
work(i)
})
}
wg.Wait()這么一看,用起來省力不少。
社區反饋
結合社區 issues 反饋中,大家也建議將 WaitGroup 的設計重心由 “計數器” 轉變為 “任務集合”,也就是文檔中主推 wg.Go 方法使用方式。
這個提案在 Go1.25 落地后是非常不錯的,因為可以去掉顯式 Add, defer 和 Done 結構,代碼更簡潔。
另外也可以避免 Add 放錯位置、忘寫 Done,以及避免 Go 老版本中的閉包捕獲錯誤等問題。
net/http:新增 CrossOriginForgeryHandler
最近 HW 行為也差不多告一段落了。這個特性還是多多少少對未來安全訴求有點作用的。但就是得等新版本了。
問題背景
@Filippo Valsorda 希望在 net/http 包中添加一個原生的 CSRF 防護處理器,以幫助開發者應對跨站請求偽造(CSRF)攻擊。
其指出瀏覽器在請求中會帶上 Origin 頭,從而我們可以基于該頭進行來源校驗,但在實際操作中他遇到了一些問題點:
- 應用自身的
origin識別復雜(例如:反向代理存在差異)。 - 需要開發者手動配置
origin,增加開發與部署復雜度。
新提案
因此其提出新提案:《net/http: add CrossOriginForgeryHandler[2]》,希望引入一種標準化處理機制來簡化這個場景。
圖片
提案核心是:引入一個新類型或中間件函數,例如:CrossOriginForgeryHandler,用于檢查請求的 Origin 或 Fetch Metadata,如 Sec-Fetch-Site。也就是類似攔截器了。
默認情形下,設計上該 handler 能自動拒絕非安全請求源(如跨站 POST 請求),并支持配置應用自身的 origin 或自定義策略。
例子
新提案中的 CrossOriginForgeryHandler 函數簽名如下:
// CrossOriginForgeryHandler rejects with a 403 Forbidden any non-safe browser
// requests that were initiated from a different origin. It protects against
// ...
type CrossOriginForgeryHandler struct {
// Handler is invoked for same-origin or non-browser requests.
Handler Handler
// ErrorHandler is invoked for cross-origin requests.
// If nil, a 403 Forbidden response is returned.
ErrorHandler Handler
// BypassOrigins is a list of origins that are allowed to send cross-origin
// requests. The values in this list must be fully-formed origins, including
// the scheme, and are compared verbatim to the [Origin] header.
//
// More complex bypass rules cam be implemented with [UnsafeAllowCrossOrigin].
//
// [Origin]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin
BypassOrigins []string
}
// UnsafeAllowCrossOrigin disables [CrossOriginForgeryHandler] for the request.
// It is generally only useful when implementing single sign-on (SSO) flows.
func UnsafeAllowCrossOrigin(r *http.Request) *http.Request示例代碼如下:
func ExampleUnsafeAllowCrossOrigin() {
mux := NewServeMux()
// 注冊其他安全敏感的路由
// ...
// 啟用 CSRF 校驗,注冊 CrossOriginForgeryHandler 攔截器,
csrfHandler := CrossOriginForgeryHandler{Handler: mux}
h := HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/sso/redirect" {
// 關閉校驗,顯式放行該 URL,跳過 CSRF 校驗
r = UnsafeAllowCrossOrigin(r)
}
csrfHandler.ServeHTTP(w, r)
})
http.ListenAndServe(":8080", h)
}社區反饋
社區普遍認可 CSRF 是一個典型需求場景,但是現在 Go 標準庫缺少開箱即用的防護中間件。
目前該提案已經 Accepted+Closed 并進入到 Go1.25 的里程碑中。
圖片
相信新版本大家大概率可以用到啦!
總結
本次給大家介紹的 Go1.25 新特性:WaitGroup.Go 和 CrossOriginForgeryHandler 的 CSRF 的防御增強。
雖然不是特別大的特性,但是他與我們的日常開發工作很接近,甚至可以直接融入開發中。還是挺不錯的。
參考資料
[1] sync: add WaitGroup.Go: https://github.com/golang/go/issues/63796
[2] net/http: add CrossOriginForgeryHandler: https://github.com/golang/go/issues/73626

































