Beego 默认不开启 XSRF 防护,必须显式配置 enablexsrf = true、自定义 xsrfkey(不能用默认值)、设置 xsrfexpire;且需在 GET 方法中调用 c.XSRFFormHTML() 并在模板中用 {{.xsrfdata}} 插入隐藏 token,否则 POST 请求将被 403 拦截。

Beego 默认不开启 XSRF 防护,必须显式配置
Beego 的 XSRF(CSRF)防护默认是关闭的,哪怕你用了 beego.Run() 启动服务,EnableXSRF 依然是 false。不手动开启,所有 POST 表单都裸奔。
开启方式只有两种,且必须同时配齐三项参数:
-
EnableXSRF = true—— 开关本身 -
XSRFKey—— 必须自定义,不能用默认值"beegoxsrf";建议用 32 字节以上随机字符串(如"61oEzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o") -
XSRFExpire—— 过期时间,单位秒,默认 3600(1 小时),太长会增加重放风险,太短会导致用户表单提交中途失效
配置位置任选其一即可,但别两边都写——容易因初始化顺序导致后写的被覆盖:
- 在
conf/app.conf中加三行:enablexsrf = true、xsrfkey = ...、xsrfexpire = 3600 - 或在
main.go的beego.Run()上方写:beego.BConfig.WebConfig.EnableXSRF = true等三句
模板里必须插入 c.XSRFFormHTML() 才生效
XSRF 防护只对 POST 请求校验,但前提是前端表单里带上了服务端生成的 token。Beego 不自动注入,得你手动塞进模板。
常见错误是只调用了 c.XSRFFormHTML() 却没正确渲染:
- 必须在 GET 处理方法中调用,比如
func (c *XsrfController) Get() { c.Data["xsrfdata"] = template.HTML(c.XSRFFormHTML()) } - 模板中必须用
{{.xsrfdata}}(注意是双大括号 + 点号),不能写成{{ xsrfdata }}或{{.XSRFData}} - 这个 HTML 片段本质是
<input type="hidden" name="_xsrf" value="...">,必须放在<form></form>标签内部,否则 POST 提交时拿不到
如果漏掉这一步,请求会直接被 Beego 拦截并返回 403,日志里出现 xsrf token missing 或 invalid xsrf token。
SQL 注入靠的是参数化查询,不是框架“自动过滤”
Beego 的 ORM 和 Raw 方法默认使用占位符(? 或命名参数),这能阻断绝大多数 SQL 注入,但前提是——你别自己拼 SQL。
典型翻车场景:
- 写
sql := "SELECT * FROM user WHERE name = '" + r.FormValue("name") + "'"→ 直接绕过所有防护 - 用
orm.Raw()时传入字符串拼接的 SQL,而不是用orm.Raw("SELECT * FROM user WHERE name = ?", name) - 把用户输入直接塞进
OrderBy、GroupBy等动态子句,这些地方 ORM 不做参数化
安全做法只有两个:
- 所有数据查询走
orm.QueryTable().Filter()等链式方法,让 ORM 控制参数绑定 - 非用原生 SQL 时,只用
?占位符,且确保参数类型与字段一致(比如整数别传字符串)
XSS 防御依赖模板自动转义,但仅限 {{.xxx}} 场景
Beego 默认模板引擎会对 {{.xxx}} 插值做 HTML 实体转义,比如把 <script></script> 变成 <script>,但这有明确边界:
- 仅对
{{.xxx}}生效,对{{.SafeHtml}}、{{template "xxx" .}}或{{.X | safe}}类型的“信任内容”不转义 - 如果后端把富文本存进数据库,又用
template.HTML()包裹后传给模板,那段 HTML 就原样输出 → XSS 漏洞开口 - 前端 JS 动态渲染(如
innerHTML = data)完全不受 Beego 控制,得靠 CSP 或 DOMPurify
真正可控的防线只有两层:入库前清洗(如用 bluemonday 库白名单过滤 HTML)、出库后严格区分「可信」和「不可信」上下文,绝不混用 template.HTML()。
Beego 的安全机制是开关式的,不是全自动的;开哪个、怎么配、在哪用,每一步都得人盯住。最常被忽略的是 XSRFKey 的硬编码和模板里 {{.xsrfdata}} 的漏写——这两个点一错,整个防护形同虚设。


















