fiber.new()默认不处理非法字符,必须手动加中间件:所有输入均为原始字符串,xss/sql注入防护需自行实现,如html.escapestring()转义、正则白名单校验、参数化查询及安全响应头设置。

使用 fiber.New() 时默认不处理非法字符,必须手动加中间件
Fiber 默认不会对请求体、URL 参数或表单数据做任何字符过滤或 XSS/SQL 注入防护。它只做路由分发和基础解析,ctx.Body()、ctx.Query()、ctx.FormValue() 返回的都是原始字符串——哪怕里面是 <script>alert(1)</script> 或 '; DROP TABLE users; --。
这意味着:你不能靠框架自动“消毒”,所有输入都得自己过一遍。常见错误是直接拼 SQL 或写入 HTML 模板,结果触发 XSS 或注入。
- 不要用
fmt.Sprintf("SELECT * FROM users WHERE name = '%s'", name)拼接 SQL - 避免在模板中用
{{.RawInput}}直接输出未转义内容(Fiber 的ctx.Render()不自动转义) - 对文件上传的
filename字段不做校验,可能写入../../etc/passwd类路径遍历
推荐用 html.EscapeString() + 正则白名单做基础过滤
Go 标准库的 html.EscapeString() 能防大部分 XSS,但它只是转义,不是过滤;真正要阻断非法输入,得结合业务规则做白名单校验。
例如用户昵称只允许中文、英文、数字、下划线和短横线:
import "regexp"
<p>var nameRe = regexp.MustCompile(<code>^[a-zA-Z0-9_\u4e00-\u9fa5\-]{2,20}$</code>)
if !nameRe.MatchString(name) {
ctx.Status(400).SendString("昵称格式不合法")
return
}
</p>
注意点:
- 正则开头结尾必须用
^和$,否则"abc<script>"</script>也会被[\w]+匹配成功 - 手机号、邮箱等字段优先用
net/mail.ParseAddress()或第三方库如govalidator验证,别手写正则 - 对 JSON 请求体,用
json.Unmarshal()解析后,再对每个字段单独校验,别在 raw body 上正则匹配
fiber.New() 的 DisableStartupMessage 和安全无关,别混淆
有人看到文档里有 DisableStartupMessage: true 就以为这是“开启安全模式”,其实它只是关掉启动日志,对输入过滤、CSP、HSTS 等零影响。
真正该配的安全项是 HTTP 头,比如:
app.Use(func(c *fiber.Ctx) error {
c.Set("X-Content-Type-Options", "nosniff")
c.Set("X-Frame-Options", "DENY")
c.Set("X-XSS-Protection", "1; mode=block")
c.Set("Content-Security-Policy", "default-src 'self'")
return c.Next()
})
但这些头只防客户端侧攻击,拦不住服务端 SQL 注入或命令执行——关键还是输入校验+参数化查询。
数据库交互必须用 db.QueryRow() 等参数化接口,禁用字符串拼接
Fiber 本身不碰数据库,但开发者常在这里翻车。Go 的 database/sql 支持占位符,必须用:
err := db.QueryRow("SELECT id FROM users WHERE email = ? AND status = ?", email, "active").Scan(&id)
而不是:
err := db.QueryRow("SELECT id FROM users WHERE email = '" + email + "' AND status = 'active'").Scan(&id) // 危险!
PostgreSQL 用户注意:$1、$2 是占位符,不是字符串插值;MySQL 用 ?;SQLite 同 MySQL。别混用,也别把用户输入当占位符值传进去。
容易忽略的一点:即使用了参数化查询,如果把用户输入用于 ORDER BY 或 TABLE NAME,仍然会中招——这些地方无法参数化,只能靠白名单映射:
sort := map[string]string{"name": "user_name", "time": "created_at"}- 从请求取
order := ctx.Query("order"),然后查if col, ok := sort[order]; ok { ... ORDER BY ` + col + ` ... } else { return error }
Fiber 不提供开箱即用的“防注入”中间件,所有过滤逻辑都得你按字段、按用途写清楚。最危险的不是没过滤,而是以为某个配置项或第三方中间件已经替你做了——结果上线后第一个 SQL 注入就出现在登录接口的 username 字段上。











