Iris中必须手动在中间件开头用ctx.Header()设置安全头,无内置SecureHeaders中间件;需统一设X-Frame-Options、X-Content-Type-Options等,且CORS中间件须注册在安全头之后以避免覆盖。

中间件里加安全头必须手动写,Iris不自动注入
Iris 没有内置的 SecureHeaders 中间件,所有安全响应头(如 X-Content-Type-Options、X-Frame-Options)都得自己用 ctx.Header() 设置。不写就不会有,也不会报错,容易误以为“默认已防护”。
常见错误现象:上线后被安全扫描工具标出 Missing X-Frame-Options 或 Unsafe Content-Type sniffing,但本地测试一切正常——因为浏览器开发工具默认不报这些,只有扫描器或严格策略环境才暴露问题。
- 必须在中间件开头或
ctx.Next()之前调用ctx.Header(),否则后续 handler 可能覆盖掉 - 不要依赖第三方中间件包(如
iris-contrib/middleware/secure),它早已停止维护且与 Iris v12+ 不兼容 -
ctx.Header()是覆盖式写入,重复调同名 header 会以最后一次为准;若需追加(如Content-Security-Policy多个 directive),得自己拼字符串
哪些头该设、怎么设才不踩坑
不是所有“推荐安全头”都适合直接套用。比如 Content-Security-Policy 若配错,页面 JS/CSS 全白屏;Strict-Transport-Security 一旦发出去,浏览器会在接下来指定时间内强制走 HTTPS,本地 HTTP 调试直接失败。
-
X-Frame-Options: DENY—— 简单有效,防点击劫持;若需嵌入 iframe,改用SAMEORIGIN,但别设成ALLOW-FROM(已被主流浏览器弃用) -
X-Content-Type-Options: nosniff—— 必加,防 MIME 类型嗅探导致 XSS;注意值必须小写nosniff,大写或空格会失效 -
X-XSS-Protection: 1; mode=block—— 仅对旧版 IE/Edge 有效,现代浏览器已忽略,可加可不加 -
Referrer-Policy: strict-origin-when-cross-origin—— 推荐,平衡隐私与功能;避免用no-referrer,否则后端日志丢失来源路径
OPTIONS 请求要单独处理安全头
前端发跨域请求时,预检(OPTIONS)请求也会经过你的中间件。但如果你只在 ctx.Next() 后设头,那 OPTIONS 响应里就漏了安全头——而 W3C 规范要求预检响应也应包含最终响应会有的安全头。
- 正确做法:在中间件开头统一设好所有安全头,再判断是否为
OPTIONS;不要把设头逻辑放在ctx.Next()后面 - 示例结构:
func SecurityHeaders(ctx iris.Context) { ctx.Header("X-Frame-Options", "DENY") ctx.Header("X-Content-Type-Options", "nosniff") ctx.Header("Referrer-Policy", "strict-origin-when-cross-origin") if ctx.Method() == "OPTIONS" { ctx.StatusCode(204) return } ctx.Next() } - 别在
OPTIONS分支里漏掉ctx.StatusCode(204),否则可能返回 200 + 空 body,某些客户端会解析失败
和 CORS 中间件共存时顺序很关键
如果你同时用了自定义安全头中间件和 CORS 中间件(比如允许 Access-Control-Allow-Origin),顺序错了会导致 CORS 头被安全头中间件覆盖,或反过来。
- 必须让 CORS 中间件在安全头中间件之后注册:先加
app.Use(SecurityHeaders),再app.Use(Cors) - 原因:
Cors中间件通常在OPTIONS分支里重写Access-Control-Allow-Headers等头,若安全头中间件在它后面执行,就会把 CORS 写的头又盖掉 - 验证方法:用
curl -I http://localhost:8080/api/test看响应头是否同时存在X-Frame-Options和Access-Control-Allow-Origin
Content-Security-Policy 和 Strict-Transport-Security 这类强约束头,上线前必须在 staging 环境用真实浏览器+DevTools 的 Security 面板验证效果,不能只靠 curl 或扫描报告。


















