目录
一、引言
二、CSRF 漏洞的概念
三、攻击者视角下的 CSRF 漏洞挖掘与利用
(一)攻击原理与条件
(二)漏洞分类及利用方式
(三)漏洞发现手法
(四)高级应用场景及绕过方法
四、防御者视角下的 CSRF 漏洞防范
(一)检测 HTTP 头部 Referer 信息
(二)使用 anti CSRF token 字段
(三)采用验证码
(四)其他防御措施
(五)安全意识教育
五、案例分析
(一)案例一:某电商平台的 CSRF 漏洞
(二)案例二:某社交网络的 CSRF 蠕虫攻击
六、结论
一、引言
在 Web 安全领域,CSRF(跨站请求伪造)漏洞是一种常见且具有潜在危害的安全漏洞。它利用了 Web 应用程序对用户请求信任的机制,通过欺骗用户在不知情的情况下执行恶意操作。本文将详细介绍 CSRF 漏洞的概念、成因、攻击原理、分类、发现手法、高级应用场景以及相应的防御手段,从攻击者和防御者的角度进行深入探讨。
二、CSRF 漏洞的概念
CSRF(Cross-site request forgery),即跨站请求伪造,是一种攻击方式。攻击者通过恶意构造网站的某些操作,将其隐藏在脚本中,然后利用 XSS 相同的注入方式(如将恶意脚本注入到页面中)或诱导用户点击执行(如发送欺诈性的链接)等手段,使拥有权限的用户在不知情的情况下执行这些操作,从而达到攻击者的目的。例如,攻击者可能诱导用户在登录状态下点击一个恶意链接,该链接会在用户所属的受信任网站上执行诸如修改密码、转账、添加管理员等操作,就好像是用户自己主动发起的请求一样。
三、攻击者视角下的 CSRF 漏洞挖掘与利用
(一)攻击原理与条件
- 攻击原理
- 首先,用户正常访问 Web A 后,Web A 在用户本地存储了 Cookie 认证信息,用于识别用户身份和维持会话。然后,攻击者诱导用户访问 Web B 上的恶意链接,该恶意链接在 Web A 上执行恶意代码,利用用户在 Web A 的认证信息,发起对 Web A 的恶意请求。例如,用户登录了银行网站 Web A,其浏览器保存了登录后的 Cookie。攻击者在恶意网站 Web B 上放置了一个隐藏的
<img>
标签,其src
属性指向银行网站 Web A 的转账接口,并携带了转账参数(如转账金额和收款账号),当用户访问 Web B 时,浏览器会自动向 Web A 发送这个转账请求,因为浏览器会带上 Web A 的 Cookie,银行网站 Web A 会认为这是用户自己发起的合法转账请求。
- 首先,用户正常访问 Web A 后,Web A 在用户本地存储了 Cookie 认证信息,用于识别用户身份和维持会话。然后,攻击者诱导用户访问 Web B 上的恶意链接,该恶意链接在 Web A 上执行恶意代码,利用用户在 Web A 的认证信息,发起对 Web A 的恶意请求。例如,用户登录了银行网站 Web A,其浏览器保存了登录后的 Cookie。攻击者在恶意网站 Web B 上放置了一个隐藏的
- 攻击条件
- 用户本地含有正常网站的认证信息:这是 CSRF 攻击的基础,通常以 Cookie 的形式存在,用于在后续的恶意请求中让受攻击网站识别为合法用户。
- 用户访问了恶意链接:攻击者需要通过各种手段诱导用户访问包含恶意代码的链接,如发送欺诈性的电子邮件、在社交平台发布诱人的链接等。
(二)漏洞分类及利用方式
- 基于数据包类型分类及利用
- Get 型 CSRF:利用
<img>
、<iframe>
、<script>
等标签的src
属性来发送 Get 请求。例如,攻击者可以构造一个恶意的<img>
标签,其src
指向目标网站的敏感操作接口(如修改用户信息的接口),并带上修改参数,诱导用户访问包含该标签的页面,从而在用户不知情的情况下修改其信息。 - POST 型 CSRF:通常使用
<form>
标签来发送 POST 请求,并且可以通过设置target
属性为_blank
或结合<frame>
标签来进行多步 CSRF 利用。例如,攻击者构造一个隐藏的<form>
表单,表单的action
指向目标网站的添加管理员接口,表单中包含添加管理员所需的参数(如用户名和密码),然后通过 JavaScript 自动提交表单,或者诱导用户点击提交按钮(可能伪装成一个看似正常的按钮)。
- Get 型 CSRF:利用
- 基于攻击目标分类及利用
- 对后台管理员进行攻击:攻击者诱骗管理员点击恶意链接,执行诸如修改管理密码、添加管理员等操作,从而获取更高的权限,进一步控制整个网站或系统。
- 修改普通用户账户和数据:如修改个人资料、手机绑定、收货地址等,侵犯用户隐私或干扰用户正常使用网站服务。
- 账户劫持:通过修改密码等操作,使合法用户失去对账户的控制,攻击者进而可以利用劫持的账户进行各种恶意活动。
- 结合其他类型漏洞进行利用:例如利用
selfxss+CSRF
,先通过selfxss
(自反射型 XSS)获取用户的 Cookie 等信息,再结合 CSRF 利用这些信息进行攻击他人;或者在后台存在Getshell
漏洞的情况下,利用 CSRF 触发Getshell
操作,获取服务器的控制权。 - CSRF 蠕虫:利用用户之间的社交关系或信任关系,诱导用户点击恶意链接,使恶意操作像蠕虫一样在用户之间传播。例如,构造一个恶意链接,当用户点击后,不仅会在用户自己的账户上执行恶意操作(如发微博、改信息等),还会自动将该链接发送给用户的好友,诱导更多用户点击,从而扩大攻击范围。
(三)漏洞发现手法
- 抓包分析敏感操作
- 对目标网站的敏感操作(如修改信息、转账、添加信息等)进行抓包。在抓包过程中,特别关注 HTTP 请求头中的
Referer
字段。通常,一个正常的请求在Referer
字段中会包含请求的来源页面信息。例如,在修改用户密码的操作中,使用 Burpsuite 的 Repeater 功能,将抓到的包放入其中,然后去掉Referer
字段,再次发送请求,观察结果是否有变化。如果没有变化,意味着服务器端可能并未对Referer
进行严格验证,这可能是一个潜在的 CSRF 漏洞点。
- 对目标网站的敏感操作(如修改信息、转账、添加信息等)进行抓包。在抓包过程中,特别关注 HTTP 请求头中的
- 检查 CSRF Token 字段
- 查看数据包中是否存在类似 CSRF Token 的字段,常见的参数有
CSRF
、token
、sid
等(一般这些字段的值都是随机字符串)。如果没有发现这些字段,就可以初步排除 CSRF Token 验证机制的存在,进一步增加了 CSRF 漏洞的可能性。
- 查看数据包中是否存在类似 CSRF Token 的字段,常见的参数有
- 针对 Ajax 提交的特殊情况
- 在某些操作对数据包的提交采用 Ajax 的情况下,需要注意数据包 HTTP 请求头是否自定义了字段。如果存在自定义字段,可能会影响 CSRF 的利用方式。此时,需要像分析
Referer
字段一样,检查服务器对这些自定义字段的验证情况,判断是否存在 CSRF 漏洞。
- 在某些操作对数据包的提交采用 Ajax 的情况下,需要注意数据包 HTTP 请求头是否自定义了字段。如果存在自定义字段,可能会影响 CSRF 的利用方式。此时,需要像分析
(四)高级应用场景及绕过方法
- Referer 验证绕过方法
- Referer 为空的情况:利用
ftp://
、http://
、http:/f if:/Jjascript
、data:
等协议构造请求。例如,当浏览器地址栏是file://
开头的 HTML 页面向任何http
站点提交请求时,这些请求的Referer
都是空的。攻击者可以构造一个file://
开头的恶意页面,其中包含指向目标网站的恶意请求,诱导用户打开该页面,从而绕过Referer
验证。 - 判断 Referer 是某域情况下绕过:如果目标网站验证
Referer
是否为某域(如*.xx.com
),攻击者可以找个二级域名(如sub.xx.com
),在该二级域名下放置恶意的<img>
标签,其src
指向目标网站的 CSRF 漏洞点,然后将包含该恶意标签的页面地址发送出去,这样当用户访问该页面时,请求的Referer
就会符合目标网站的验证要求,从而成功伪造请求。 - 判断 Referer 是否存在某关键词绕过:如果
Referer
判断存在不存在某个关键词(如google.com
),攻击者可以在网站新建一个包含该关键词的目录(如google.com
目录),将 CSRF 攻击代码存放在该目录下,然后诱导用户访问该目录下的页面,这样请求的Referer
就会包含该关键词,从而绕过验证。 - 判断 Referer 是否有某域名绕过:如果判断了
Referer
开头是否以某个域名(如126.com
)及子域名不测试不验证根域名为126.com
,攻击者可以构造子域名(如x.126.com.xxx.com
)作为蠕虫传播的载体服务器,将 CSRF 攻击代码放置在该服务器上,诱导用户访问,从而绕过Referer
验证。
- Referer 为空的情况:利用
- CSRF 结合其他漏洞利用
- 例如,在一个严格验证
Referer
的敏感操作场景下,结合同域下的一个 URL 跳转漏洞和一台 VPS(虚拟专用服务器),可以构建一个完整的 CSRF 蠕虫。攻击者首先利用 URL 跳转漏洞将用户重定向到恶意服务器(VPS)上的页面,该页面包含 CSRF 攻击代码,然后利用 CSRF 攻击执行敏感操作,如修改用户信息、发布恶意内容等,并且通过恶意代码让用户自动将包含攻击代码的链接发送给其他用户,从而实现蠕虫式传播。在后台存在Getshell
漏洞的情况下,攻击者可以利用 CSRF 触发Getshell
操作,获取服务器的控制权。例如,构造一个恶意的 CSRF 请求,指向后台的Getshell
漏洞利用点,当管理员或具有相应权限的用户被诱导点击恶意链接后,就可能导致服务器被攻击者控制。
- 例如,在一个严格验证
- 多步 CSRF 利用
- 利用
<form>
标签的target=_black
或结合<frame>
标签进行多步 CSRF 利用。例如,攻击者可以构造一个包含多个<form>
表单的页面,每个表单对应一个步骤的操作,通过设置target
属性将表单提交到不同的目标(如隐藏的<iframe>
中),从而实现多步的恶意操作,如先修改用户密码,再利用修改后的密码登录并获取用户的敏感信息等。
- 利用
四、防御者视角下的 CSRF 漏洞防范
(一)检测 HTTP 头部 Referer 信息
-
原理及实现(Java 示例)
- 在敏感操作步骤中,服务器端收到请求后,先检测
Referer
是否为本域的请求。在 Java Web 应用中,可以使用 Servlet 过滤器来实现对Referer
的检测。以下是一个简单的示例代码:
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebFilter(“/sensitive/*”) // 对敏感操作路径进行过滤
public class CSRFRefererFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws ServletException, IOException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;String referer = request.getHeader("Referer");if (referer == null ||!referer.startsWith(request.getScheme() + "://" + request.getServerName())) {response.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid Referer");return;}filterChain.doFilter(request, response); }@Override public void destroy() {Filter.super.destroy(); }
}
- 在敏感操作步骤中,服务器端收到请求后,先检测
- 在上述代码中,
CSRFRefererFilter
过滤器会拦截对/sensitive/*
路径下的请求(假设这些是敏感操作的路径),获取请求头中的Referer
字段,判断其是否为空或是否以本域开头,如果不符合要求,则返回403 Forbidden
错误,阻止请求继续执行。
(二)使用 anti CSRF token 字段
-
原理及实现(Python 示例,生成和验证 token)
- 在请求表单中加入
anti CSRF token
字段是一种常见且有效的防御方法。token
是一个随机生成的字符串,在用户访问页面时生成并嵌入到表单中,同时在服务器端保存该token
的副本。当用户提交表单时,服务器端验证提交的token
是否与服务器保存的一致。以下是一个简单的 Python 示例,用于生成和验证token
:
import random
import stringdef generate_token():
return ‘’.join(random.choices(string.ascii_letters + string.digits, k=32)) # 生成一个32位的随机字符串作为tokendef validate_token(token, stored_token):
return token == stored_token - 在请求表单中加入
- 在实际应用中,需要在用户访问包含表单的页面时生成
token
,并将其存储在服务器端(如存储在用户会话中或数据库中),然后在表单中添加一个隐藏字段包含该token
。当表单提交时,服务器端获取提交的token
并与存储的进行比较,如果不一致,则拒绝请求。
(三)采用验证码
- 原理及应用场景
- 对于一些重要的操作,如修改密码、转账等,可以采用验证码的形式来增加攻击者利用 CSRF 的难度。验证码要求用户输入只有人类能够识别的字符或图像内容,这样攻击者就无法通过自动化的 CSRF 攻击来执行这些操作。例如,在修改密码的页面上,生成一个包含随机数字和字母的验证码图片,用户需要输入正确的验证码才能提交密码修改请求。这样,即使攻击者构造了恶意的 CSRF 请求,由于无法获取验证码内容,也无法成功执行密码修改操作。
(四)其他防御措施
-
SameSite 属性设置(Cookie 相关)
- 可以为 Cookie 设置
SameSite
属性,该属性可以限制 Cookie 在跨站请求中的发送行为。例如,将SameSite
设置为Strict
,则只有当请求来自与 Cookie 所属站点相同的站点时,才会发送 Cookie,这可以有效防止 CSRF 攻击中利用用户的 Cookie 进行恶意请求。在 Java 中,设置 Cookie 的SameSite
属性可以通过Cookie
类的setSameSite
方法(在 Servlet 3.0 及以上版本支持),以下是一个简单示例:
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;public class CookieSettingServlet extends javax.servlet.http.HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
Cookie cookie = new Cookie(“myCookie”, “cookieValue”);
cookie.setSameSite(Cookie.SameSite.STRICT); // 设置SameSite属性为Strict
response.addCookie(cookie);
}
} - 可以为 Cookie 设置
-
定期安全审计和漏洞扫描
- 定期进行安全审计,检查网站的代码和配置,查找可能存在的 CSRF 漏洞。可以使用专业的漏洞扫描工具(如 Nessus、OpenVAS 等)对网站进行扫描,这些工具可以检测出常见的 CSRF 漏洞模式以及其他安全问题。
- 对于 Nessus,它具有丰富的漏洞库,能够对网站进行全面的安全评估。在使用 Nessus 进行 CSRF 漏洞扫描时,首先需要配置扫描目标,即网站的 URL 地址。然后,可以根据实际需求选择合适的扫描策略,例如针对 Web 应用程序的扫描策略,该策略会重点检查与 Web 相关的安全问题,包括 CSRF 漏洞。扫描完成后,Nessus 会生成详细的报告,报告中会列出发现的漏洞,包括漏洞的名称、严重程度、所在位置等信息。安全人员可以根据报告中的信息进一步分析和处理 CSRF 漏洞。
- OpenVAS 同样是一款强大的漏洞扫描工具。它提供了图形化界面和命令行两种操作方式。在使用 OpenVAS 扫描 CSRF 漏洞时,需要先进行系统配置,如更新漏洞库等操作。然后创建扫描任务,指定目标网站和扫描配置。扫描过程中,OpenVAS 会对网站的各种请求和响应进行分析,检测是否存在 CSRF 漏洞特征。扫描结束后,其报告也会清晰地展示发现的漏洞情况,帮助安全人员及时了解网站的安全状态并采取相应的修复措施。
- 同时,建立安全监控机制,实时监测网站的访问和操作,及时发现异常的请求行为,如大量来自不同 IP 的疑似 CSRF 攻击请求等,并及时采取措施进行防范和应对。例如,可以使用日志分析工具(如 ELK Stack)对网站的访问日志进行实时分析,通过设置规则来识别可能的 CSRF 攻击行为,一旦发现异常,立即触发警报并采取相应的措施,如暂时封锁可疑 IP 地址、暂停相关操作等,以保护网站和用户的安全。
(五)安全意识教育
- 用户教育
- 开发人员培训
五、案例分析
(一)案例一:某电商平台的 CSRF 漏洞
- 漏洞发现过程
- 攻击者在对某电商平台进行测试时,发现其修改收货地址的功能存在 CSRF 漏洞。通过抓包分析,发现修改收货地址的请求为 POST 类型,且请求中没有 CSRF Token 字段。进一步测试发现,服务器端对
Referer
字段的验证不严格,当去掉Referer
字段后,请求仍然能够成功执行。
- 攻击者在对某电商平台进行测试时,发现其修改收货地址的功能存在 CSRF 漏洞。通过抓包分析,发现修改收货地址的请求为 POST 类型,且请求中没有 CSRF Token 字段。进一步测试发现,服务器端对
- 攻击利用方式
- 攻击者构造了一个恶意的 HTML 页面,其中包含一个隐藏的
<form>
表单,表单的action
指向电商平台的修改收货地址接口,表单中包含了攻击者想要修改的收货地址信息。然后,攻击者通过电子邮件或社交平台等方式诱导用户访问该恶意页面。当用户在登录电商平台的状态下访问该页面时,浏览器会自动提交表单,由于服务器端未对Referer
进行有效验证且无 CSRF Token 保护,修改收货地址的请求被成功执行,用户的收货地址被修改为攻击者指定的地址,这可能导致用户购买的商品被发送到错误的地址,给用户带来损失。
- 攻击者构造了一个恶意的 HTML 页面,其中包含一个隐藏的
- 修复措施
- 电商平台在发现漏洞后,采取了一系列修复措施。首先,在修改收货地址的表单中添加了
anti CSRF token
字段,在用户访问页面时生成并嵌入到表单中,同时在服务器端进行严格验证。其次,加强了对Referer
字段的验证,确保请求来自本域。此外,对整个平台的其他敏感操作进行了全面检查,以防止类似漏洞的存在。
- 电商平台在发现漏洞后,采取了一系列修复措施。首先,在修改收货地址的表单中添加了
(二)案例二:某社交网络的 CSRF 蠕虫攻击
- 漏洞发现过程
- 攻击者在研究某社交网络的功能时,发现其分享功能存在 CSRF 漏洞,且该社交网络存在同域下的 URL 跳转漏洞。通过分析发现,分享操作的请求没有 CSRF Token 保护,并且对
Referer
的验证存在缺陷,允许来自特定二级域名的请求。
- 攻击者在研究某社交网络的功能时,发现其分享功能存在 CSRF 漏洞,且该社交网络存在同域下的 URL 跳转漏洞。通过分析发现,分享操作的请求没有 CSRF Token 保护,并且对
- 攻击利用方式
- 攻击者利用这些漏洞构造了一个恶意的 CSRF 攻击链。首先,攻击者在恶意服务器上创建一个包含 CSRF 攻击代码的页面,该页面利用社交网络的分享功能接口,构造了一个恶意的分享请求,将攻击者指定的内容(如恶意广告或欺诈信息)设置为分享内容。然后,攻击者通过找到社交网络的一个 URL 跳转漏洞,将用户从正常的社交网络页面重定向到恶意服务器上的攻击页面。当用户在登录社交网络的状态下被重定向到攻击页面时,由于分享功能存在 CSRF 漏洞且
Referer
验证可被绕过,用户的浏览器会自动执行分享操作,将恶意内容分享到用户的社交网络圈子中。而其他用户看到分享内容后,如果点击链接,又会被重定向到恶意服务器,从而形成蠕虫式传播,导致恶意内容在社交网络中迅速扩散,严重影响了社交网络的正常秩序和用户体验。
- 攻击者利用这些漏洞构造了一个恶意的 CSRF 攻击链。首先,攻击者在恶意服务器上创建一个包含 CSRF 攻击代码的页面,该页面利用社交网络的分享功能接口,构造了一个恶意的分享请求,将攻击者指定的内容(如恶意广告或欺诈信息)设置为分享内容。然后,攻击者通过找到社交网络的一个 URL 跳转漏洞,将用户从正常的社交网络页面重定向到恶意服务器上的攻击页面。当用户在登录社交网络的状态下被重定向到攻击页面时,由于分享功能存在 CSRF 漏洞且
- 修复措施
- 社交网络平台在得知漏洞后,立即采取了紧急修复措施。针对 CSRF 漏洞,在分享功能的请求中添加了严格的
anti CSRF token
验证机制,确保请求的合法性。同时,修复了 URL 跳转漏洞,对跳转的目标进行严格的白名单限制,防止被恶意利用。此外,加强了对整个平台的安全监控,实时监测类似的异常请求行为,一旦发现,及时采取措施进行阻止和清理,如删除恶意分享内容、封锁相关恶意 IP 地址等,以防止类似攻击再次发生。
- 社交网络平台在得知漏洞后,立即采取了紧急修复措施。针对 CSRF 漏洞,在分享功能的请求中添加了严格的
六、结论
CSRF 漏洞是 Web 安全领域中一个不容忽视的问题,攻击者不断寻找利用这些漏洞的方法,而防御者需要采取多种有效的防御措施来保护 Web 应用程序和用户的安全。从攻击者的角度来看,了解 CSRF 漏洞的各种利用方式和绕过方法有助于发现和利用这些漏洞;从防御者的角度出发,通过检测Referer
、使用anti CSRF token
、验证码、合理设置 Cookie 属性、定期安全审计、安全意识教育以及及时处理漏洞案例等措施,可以有效地降低 CSRF 漏洞带来的风险,确保 Web 应用程序的安全性和用户数据的保密性、完整性与可用性。在实际的 Web 安全防护中,需要综合运用多种技术和方法,不断更新防御策略,以应对不断变化的安全威胁。同时,持续关注行业动态和安全研究成果,及时将新的防御技术应用到实际的 Web 应用开发和运维中,也是保障 Web 安全的重要环节。