服务安全:输入校验、SQL 注入、CSRF 概念
一句话结论:Web 安全按“不可信输入”这条主线展开——输入校验是第一道防线(长度/类型/白名单/枚举,用 validator 收口),SQL 注入靠“值一律参数化、标识符一律白名单”根治;CSRF 针对“浏览器自动带 Cookie 发起跨站请求”的认证盲区,主防线是 SameSite Cookie,辅以 CSRF token 或 Origin 校验。用 Bearer Token(Authorization 头)而非 Cookie 的纯 API 天然少受 CSRF 影响。记住分层:传输(HTTPS)→ 认证 → 授权 → 输入校验 → 输出编码 → 日志脱敏。
三类问题速览
| 威胁 | 成因 | 防御 |
|---|---|---|
| 输入注入/越界 | 直接信任外部输入 | 校验长度/格式/白名单,validator 集中做;拒绝而非拼接 |
| SQL 注入 | 字符串拼 SQL 改变语句结构 | 参数化占位符;表名/排序等标识符用白名单映射 |
| CSRF | 浏览器自动携带 Cookie,跨站请求被当成已登录用户 | SameSite Cookie + CSRF token / Origin 校验 |
输入校验与 SQL 注入示例
// 校验:白名单优于黑名单
if !slices.Contains([]string{"pending", "paid", "closed"}, c.PostForm("status")) {
resp.Fail(c, ErrInvalidParam); return
}
// 正确:值走占位符,GORM 自动参数化
db.Where("name = ? AND status = ?", name, status).Find(&list)
// 错误示范(面试必答):永远不要 fmt.Sprintf 拼值
// db.Where(fmt.Sprintf("name = '%s'", name)) // 注入点
// 标识符(表名/排序字段)无法占位:白名单映射
order := sortWhitelist[c.Query("sort")] // 查不到给默认值
CSRF 详解
- 原理:用户登录后浏览器存了 Session Cookie;攻击页面诱导浏览器向目标站发 POST(转账/改密),Cookie 自动带上,服务端误判为本人操作。
- 为什么 Bearer Token API 不受影响:浏览器不会自动往跨站请求加 Authorization 头,攻击者拿不到 token。
- Cookie 方案防护:① SameSite=Lax/Strict(现代浏览器主防线);② CSRF token(同步令牌:页面下发随机 token,提交时带回校验;double-submit cookie 变体);③ 校验 Origin/Referer 同源。
- 别忽略的配套:XSS 会偷 token/Cookie(HttpOnly 防 JS 读 Cookie),所以输出编码与 CSP 也要跟上;敏感操作加验证码/二次确认兜底。
其他要点
- 错误信息别回显堆栈/SQL(见错误码章节);日志不记密码、token、身份证、卡号(见日志章节)。
- 依赖与基线:用 govulncheck 扫依赖漏洞;安全头 HSTS/CSP/X-Frame-Options 按需加。
- 接口侧:限流防爆破(见限流章节)、越权检查(见鉴权章节)。
追问记忆点
- 追问:参数化查询能防所有注入吗?——防“值”的注入;标识符(表名、列名、排序)无法占位,必须白名单。
- 追问:为什么 SameSite 还不够?——老浏览器不支持、子域场景、跨站 GET 链接跳转等仍有盲区,关键操作叠加 token/Origin 校验。
- 追问:CSRF 和 XSS 什么关系?——XSS 能偷 token 或直接冒充用户发请求,等于绕过 CSRF 防护;两者要一起防。
- 记忆点:输入白名单校验、SQL 值参数化+标识符白名单、CSRF 靠 SameSite+token/Origin;纯 token API 风险天然低。