课程名称:计算机网络应用 核心摘要:本讲围绕 CSRF(跨站请求伪造)的防护策略展开,从"识别伪造请求"与"二次校验"两个维度入手。重点讲解利用 HTTP Referer 头部进行来源校验(防盗链思想),并通过过滤器/拦截器在网关或微服务中实现防护;同时介绍原密码校验、验证码、人脸识别等二次校验手段,构建多层次的 CSRF 防御体系。
- CSRF(Cross-Site Request Forgery,跨站请求伪造):攻击者诱导已登录用户在第三方页面发起对目标站的请求,利用浏览器自动携带的 Cookie 完成伪造操作。
- 防护总思路:从两个方向入手
- 区分请求是否为伪造 —— 通过
Referer 头部判断请求来源。 - 二次校验 —— 在关键操作上增加额外的身份/意图确认。
- Referer 头部:HTTP 请求头字段,标识当前请求是从哪个页面/链接发出的,是服务端判断请求来源的依据,常用于防盗链与 CSRF 校验。
| 场景 | Referer 取值 | 是否合法 |
|---|
| 单击黑客诱导链接(异常) | http://www.hacker.com | 否,来自外部域名 |
| 正常登录后单击"重置密码"(正常) | http://www.edu.com/admin/userList | 是,来自本域名 |
结论:正常请求一定从本域名页面发出;伪造请求的 Referer 指向攻击者站点,服务端据此可拒绝非法请求。
| 实现位置 | 方式 | 说明 |
|---|
| 流量网关 | 过滤器(Filter) | 全局大方向校验,所有进入微服务的请求统一过滤 |
| 微服务 | 过滤器 / 拦截器(Interceptor) | 针对安全性要求高的具体服务做精细控制 |
| 业务代码 | 直接在业务方法中校验 | 灵活但分散,适合关键接口单独加固 |
| 多重防护 | 网关 + 业务代码 | 多层校验,安全性更高 |
- 通过
request.getHeader("referer") 获取来源链接。 - 判断是否为
null 或空字符串。 - 与当前域名做前缀比对,不一致则直接拒绝请求。
- 例外情况:首次登录时用户可能在地址栏直接输入 URL,此时
Referer 为空字符串,需放行,避免误拦。
| 校验方式 | 应用场景 | 防护特点 |
|---|
| 原密码校验 | 修改密码 | 攻击者不知道原密码,无法伪造 |
| 图形验证码 | 转账、敏感操作 | 阻止"傻瓜式"自动化批量攻击 |
| 人脸识别 / 指纹 | 支付、交易确认 | 生物特征二次认证,当前主流业务方案 |
String referer = request.getHeader("referer");
if (referer == null || "".equals(referer)) {
return;
}
String scheme = request.getScheme();
String serverName = request.getServerName();
String expectedPrefix = scheme + "://" + serverName;
if (!referer.startsWith(expectedPrefix)) {
return;
}
- 正常流程:登录系统 → 打开 F12 调试 → 单击"重置密码" → Referer 为本域名 → 重置成功。
- 攻击流程:访问黑客站点(hacker.com)→ 单击诱导链接 → 请求 Referer 指向 hacker.com → 服务端校验失败 → 提示"非法访问"。
- 考点 1:CSRF 防护的两大方向 —— Referer 来源校验 + 二次校验。
- 考点 2:Referer 头部的作用:记录请求来源,可用于防盗链与 CSRF 防护。
- 易错点:首次登录(地址栏直接输入 URL)时
Referer 为空,校验逻辑必须做例外放行,否则会误拦正常用户。 - 易错点:
startsWith 比对时需拼接协议 + 域名(http://edu.com),不能只比对域名,否则可能被相似前缀绕过。 - 面试题:为什么 Referer 校验能防 CSRF?它有哪些局限性?(如部分浏览器/隐私设置会去除 Referer,需结合 Token 等方案)。
- 面试题:网关层与业务层做 CSRF 校验的区别与取舍。
- 高频混淆:
Referer 字段名实际拼写为 Referer(历史拼写错误),而非 Referrer。
- 当浏览器隐私策略或 HTTPS→HTTP 跳转导致
Referer 被去除时,仅靠 Referer 校验是否仍可靠?是否需要引入 Anti-CSRF Token、SameSite Cookie 等方案作为补充? - 双重提交 Cookie(Double Submit Cookie) 与 Synchronizer Token(同步令牌) 模式如何实现?后续课程是否会讲解?
- 在微服务架构下,网关统一校验 Referer 后,是否还需要在每个微服务中重复实现拦截器?如何权衡性能与安全?
- Spring Security 是否提供了开箱即用的 CSRF 防护机制?与手写过滤器/拦截器相比优劣如何?