必须手动设置四个基础安全头:X-Content-Type-Options、X-Frame-Options、X-XSS-Protection、Strict-Transport-Security;CSP需严格语法、禁拼接、用nonce;中间件须在next()前调用Header.Set();/health和/static需单独防护。

直接在 fiber.New() 后注册中间件,用 ctx.Response().Header.Set() 设置关键头;别依赖框架默认值,也别在 handler 里零散写——漏一个路径就等于开一扇门。
必须手动设置的四个基础安全头
Go 框架不自动加任何防护头,Fiber 尤其“裸”:fiber.Default() 只加日志和 panic 捕获,跟安全无关。这四个头得你亲自塞进响应链:
-
X-Content-Type-Options: nosniff—— 防止浏览器把image/jpeg当 HTML 执行(比如上传恶意 .jpg) -
X-Frame-Options: DENY—— 禁止 iframe 嵌套,防点击劫持;若真需同源嵌入,改用SAMEORIGIN,但别写成sameorigin(大小写敏感) -
X-XSS-Protection: 1; mode=block—— 触发浏览器 XSS 过滤器(现代浏览器已弱化,但仍是兜底) -
Strict-Transport-Security: max-age=31536000; includeSubDomains—— 仅 HTTPS 下生效,本地开发(r.TLS == nil)时跳过,否则 Chrome 会拒绝加载
Content-Security-Policy 头不能拼接字符串
CSP 是最易配置出错的安全头:一个引号漏了、空格多一个、指令名写错,整条策略就被浏览器静默忽略。常见失效现象是 DevTools Security 标签页显示 “delivered but not enforced”。
- 值必须用单引号包裹指令,如
script-src 'self' https://cdn.example.com;整个字符串用双引号包 - 禁止拼接用户输入(比如把前端传的域名直接塞进 CSP),否则等于自己开 XSS 入口
- 动态 nonce 必须用
crypto/rand生成,再注入模板或响应体;别手写固定值 - 静态文件服务(
app.Static())默认不走中间件,需单独包装 handler 或显式调用c.Set("Content-Security-Policy", ...)
中间件注册顺序决定头是否生效
Fiber 中间件是线性执行的,ctx.Response().Header.Set() 必须在 next() 之前调用,且越早越好——某些第三方中间件(比如日志、压缩)可能在 next() 后偷偷覆写 header。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
立即学习“go语言免费学习笔记(深入)”;
- 错误姿势:
next()执行完再设头 → 此时响应已开始写出,header 被锁死 - 正确姿势:在中间件函数第一行就调用
c.Response().Header.Set() - 别用
c.Append()或c.Set()替代c.Response().Header.Set(),前者是为 cookie 和通用 header 设计,对 CSP 等严格语法头不保险 - 如果用了
helmet.New()这类封装库,确认它没在内部调用WriteHeader(0)提前触发写入
为什么 /health 和 /static 容易漏掉防护
健康检查和静态资源是最常被忽略的路径:它们往往绕过主路由逻辑,不经过你精心写的中间件链,导致攻击者从 /favicon.ico 或 /health 入口绕过所有防护。
-
app.Static("/static", "./public")必须在安全中间件注册之后?错——它得在之前注册,否则中间件会拦截/static/*请求并加头,但实际Static内部有自己的响应逻辑,头可能被覆盖 - 稳妥做法:把安全头中间件放在
app.Use()最顶部,然后注册Static,再注册其他路由;或者给Static单独套一层 wrapper handler 显式加头 -
/healthhandler 里也要手动调一次c.Response().Header.Set(),别指望中间件自动覆盖——Fiber 的Static和Get注册是独立分支,中间件链不保证穿透所有路径
真正难的不是写那几行 Set(),而是确保每个字节流出前,头都已确定、未被覆盖、语法无误。生产环境上线前,用 curl -I 或浏览器 DevTools 检查每类路径(/、/api、/static/logo.png、/health)的实际响应头,一个都不能少。

















