helmet.new()仅设基础安全头,不防xss/csrf;需显式配置csp、禁用fiber.default()、在fiber.new()后首位挂载,否则防护失效。

fiber.Helmet() 不等于自动防 XSS/CSRF
直接调用 helmet.New() 只设置基础响应头,比如 X-Content-Type-Options: nosniff、X-Frame-Options: SAMEORIGIN,它不生成 CSRF Token,不校验 Referer,也不启用 CSP。很多团队上线后扫出 XSS 告警,回查发现只挂了 helmet.New() 就以为万事大吉——这是最典型的误判。
必须显式传入 ContentSecurityPolicy 字段才能激活 CSP:
<pre class="brush:php;toolbar:false;">helmet.New(helmet.Config{
ContentSecurityPolicy: "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'",
})
否则浏览器根本不会执行 CSP 策略,XSS 防护形同虚设。
CSP 配置必须匹配前端实际资源加载方式
React/Vue 应用常依赖内联脚本或样式,'unsafe-inline'
- 若用了 CDN 加载字体,得加
font-src 'self' https://fonts.googleapis.com - 若接口走不同域名,
connect-src要明确列出,不能只靠default-src -
script-src中若含'unsafe-eval',说明用了new Function()或eval(),应优先重构而非放行
漏配某类资源策略,会导致对应资源被浏览器静默拦截,页面功能异常但控制台报错极不直观。
Strict-Transport-Security 和 X-Frame-Options 的取舍要按场景
Strict-Transport-Security: max-age=31536000; includeSubDomains 对 HTTPS 全站强制有效,但开发环境若混用 HTTP,会直接导致页面无法加载——本地调试务必关掉或降级为 max-age=0。
X-Frame-Options: DENY 太粗暴:现代管理后台常需嵌入 iframe(如报表看板),此时应换用 Content-Security-Policy: frame-ancestors 'self' https://dashboard.example.com',并确保该策略和 helmet.New() 的其他头不冲突。
Helmet 必须在中间件链最前注册,且不能和 fiber.Default() 混用
安全头必须在响应生成前写入,否则被后续中间件覆盖。正确顺序是:
<pre class="brush:php;toolbar:false;">app := fiber.New() // 注意:不是 fiber.Default()
app.Use(helmet.New(...))
app.Use(cors.New(...)) // CORS 也要在路由前
app.Get("/api/data", handler)
如果用 fiber.Default()
Logger(打印完整 Authorization 头)和 Recover(暴露 panic 堆栈),这时再挂 helmet.New() 已经晚了——敏感信息早随错误响应发出去了。
生产环境的安全配置起点只能是 fiber.New(),所有中间件都得手动挂载,没有“默认安全”这回事。











