beego默认不注入安全头,需通过filter手动配置x-content-type-options、x-frame-options、strict-transport-security等;csp须先用report-only模式观察再收紧,避免白屏。

Beego默认不自动注入安全头
Beego 2.x 版本(包括 2.3.5)本身不会默认添加 X-Content-Type-Options、X-Frame-Options、Content-Security-Policy 等安全响应头。你看到的“Beego支持安全头”描述,是指它允许你通过中间件或过滤器手动注入,而非开箱即用。
如果不主动配置,所有响应头都由 Go 标准库 http.ResponseWriter 原生输出,没有任何防护性头字段。这意味着你的 API 或页面默认暴露在 MIME 类型嗅探、点击劫持、XSS 注入等风险下。
用 Filter 注入安全头最直接有效
Beego 的 Filter 是插入响应头的推荐方式,它在 Controller 执行后、响应写出前生效,避免被后续逻辑覆盖。
- 在
routers/router.go中注册全局 Filter(通常放在init()函数末尾):
beego.InsertFilter("/*", beego.BeeApp.Handlers, func(ctx *context.Context) {
ctx.ResponseWriter.Header().Set("X-Content-Type-Options", "nosniff")
ctx.ResponseWriter.Header().Set("X-Frame-Options", "DENY")
ctx.ResponseWriter.Header().Set("X-XSS-Protection", "1; mode=block")
ctx.ResponseWriter.Header().Set("Referrer-Policy", "strict-origin-when-cross-origin")
}, false)
-
"/*"表示匹配全部路由;如只需保护 API,可改用"/api/*" - 最后一个参数
false表示该 Filter 不影响 panic 恢复流程(保持RecoverPanic=true生效) - 注意:不要在 Controller 的
Prepare()或Finish()里设头——Prepare()太早(可能被后续覆盖),Finish()已错过写头时机
HTTPS + 安全头必须同步启用 Strict-Transport-Security
如果你已按规范启用了 HTTPS(EnableHTTPS = true 且 EnableHttpTLS = true),但没加 Strict-Transport-Security 头,用户首次访问仍可能走 HTTP,中间人可劫持并降级连接。
- 务必在上述 Filter 中补上这一行:
ctx.ResponseWriter.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
-
max-age=31536000是一年(推荐最小值),浏览器收到后会强制后续请求走 HTTPS,即使用户手动输http:// - 若部署在 Nginx 后端且 Nginx 终止 TLS,则 HSTS 必须由 Nginx 设置,Beego 中设置无效(响应从 Nginx 发出,Beego 的头被丢弃)
- 本地开发用自签名证书时,
curl -k或浏览器会忽略 HSTS,但上线前必须验证真实证书下该头是否生效(用curl -I https://yoursite.com检查响应头)
Content-Security-Policy 需按业务定制,不能硬编码通用值
Content-Security-Policy(CSP)是防御 XSS 最有效的机制之一,但 Beego 不提供自动策略生成。填错会导致脚本、样式、图片全部被拦截,页面白屏。
- 先用 report-only 模式观察(不阻断,只上报违规):
ctx.ResponseWriter.Header().Set("Content-Security-Policy-Report-Only", "default-src 'self'; script-src 'self' 'unsafe-inline' https:; img-src *; report-uri /csp-report")
- 上线前必须移除
-Report-Only后缀,并收紧策略,例如去掉'unsafe-inline',改用 nonce 或 hash - Beego 模板中内联 JS/CSS 需配合
{{.XSRFToken}}或自定义 context 变量注入 nonce,否则无法通过 CSP - 如果用了第三方 CDN(如 jQuery、Bootstrap),需显式加入
script-src和style-src白名单,例如https://cdn.jsdelivr.net
CSP 是最容易配错也最难调试的安全头——它不报错,只静默屏蔽资源。上线前务必在 Chrome DevTools 的 Console 和 Network 标签下确认无 “Refused to load” 类警告。











