Go+Iris需在输入校验、模板渲染、响应头CSP三环节设防:用html/template自动转义、白名单过滤用户输入、设置Content-Security-Policy,缺一不可。

Go + Iris 框架本身不自动拦截或转义用户输入,XSS 防御必须由开发者显式介入——不是“开个开关就安全”,而是要在输入解析、模板渲染、响应输出三个关键环节分别设防。
模板渲染时必须用 html/template,禁用 text/template
Iris 默认支持两种模板引擎,但只有 html/template 提供自动 HTML 转义能力。若误用 text/template(比如手动调用 iris.TmplEngine().AddFunc 时传错配置),所有 {{.UserInput}} 都会原样输出,<script></script> 直接执行。
- 确保模板文件后缀为
.html或显式指定iris.HTML(...).Delims("[[", "]]")等配置,触发html/template行为 - 避免在模板中使用
{{.RawHTML | safe}}类似写法——Iris 没有内置safe函数,强行定义等于自毁防线 - 若需插入可信 HTML(如富文本编辑器内容),必须先用
DOMPurify或bluemonday库清洗,再通过template.HTML类型强制绕过转义
context.PostForm 和 context.URLParam 返回的是原始字符串,不做任何过滤
Iris 的参数获取方法(如 ctx.PostForm("content"))只做类型转换和空值处理,不会对内容做 XSS 相关清洗。这意味着你拿到的可能是 ,直接存库或塞进模板就中招。
- 对所有用户输入字段(表单、URL 参数、JSON body)执行白名单校验:例如评论内容只允许中文、英文字母、数字、常见标点,用正则
^[\u4e00-\u9fa5a-zA-Z0-9\s,。!?;:“”‘’()【】《》、]+$过滤 - 若需保留部分 HTML 标签(如
、),不要手写替换逻辑,改用bluemonday定义策略:bluemonday.UGCPolicy().Sanitize(input) - 禁止对
ctx.Request().Body做多次io.ReadAll——Iris 的ctx.ReadJSON已读取一次,再读会返回空
响应头必须设置 Content-Security-Policy,不能只靠转义
仅靠模板转义防不住 DOM 型 XSS(比如 innerHTML = user.input)和 Base64 编码绕过。CSP 是最后一道强制防线,Iris 提供 ctx.Response.Header().Set 直接注入。
- 基础策略示例:
ctx.Response.Header().Set("Content-Security-Policy", "default-src 'self'; script-src 'self' 'unsafe-inline' https:; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:") -
'unsafe-inline'仅在必须支持内联style或小段脚本时临时开启,上线前应移除并迁移到外部文件 - 避免使用
data:协议加载脚本(如javascript:alert(1)),CSP 中显式禁用:script-src 'self'不带data:
真正容易被忽略的点是:XSS 防御链条里,**模板转义管输出、参数校验管输入、CSP 管执行环境**,三者缺一不可。少一个环节,攻击者就能从 URL 参数 → 绕过校验 → 注入到模板 → CSP 失效 → 执行成功。别指望某个中间件包能一劳永逸。











