一.基本概念
1.定义
跨站请求伪造(Cross - Site Request Forgery,缩写为 CSRF)漏洞是一种网络安全漏洞。它是指攻击者通过诱导用户访问一个恶意网站,利用用户在被信任网站(如银行网站、社交网站等)的登录状态,在用户不知情的情况下,让用户的浏览器向被信任网站发送非用户本意的请求,从而执行一些操作,比如修改用户信息、进行转账等操作。
2.示例
-
假设用户已经登录了一个网上银行网站bank.com,其会话 ID 存储在浏览器的 Cookie 中。攻击者创建了一个恶意网站evil.com,在这个网站上有如下 HTML 代码:
<form action="https://bank.com/transfer" method="post"> <input type="hidden" name="amount" value="1000" /> <input type="hidden" name="recipient" value="attacker_account" /> </form> <script> document.forms[0].submit(); </script>
-
当用户访问evil.com时,浏览器会自动提交这个表单,向bank.com发送一个转账请求。由于浏览器会带上用户在bank.com的会话 Cookie,bank.com会认为这个请求是用户自己发起的,从而可能导致用户的资金被盗转。
3.危害
- 用户数据泄露和篡改:攻击者可以通过 CSRF 漏洞获取用户的敏感信息,如修改用户密码、邮箱地址等,从而进一步控制用户账户。
- 经济损失:在涉及金融交易的网站上,攻击者可以利用 CSRF 漏洞进行非法转账、购物等操作,给用户造成直接的经济损失。
- 破坏系统功能和信誉:可以对系统的正常功能造成干扰,如大量发送虚假请求,导致系统资源被滥用。同时,也会影响用户对网站的信任,损害网站的信誉。
二.漏洞类型
GET型CSRF
1.定义
GET 型 CSRF(Cross - Site Request Forgery)是 CSRF 攻击的一种类型。在这种攻击方式中,攻击者诱导用户的浏览器发起一个 HTTP GET 请求,利用用户在目标网站的登录状态,在用户不知情的情况下执行目标网站上的某些操作。
2.攻击流程
-
构造恶意链接:攻击者首先会构造一个包含恶意请求的链接。因为 HTTP GET 请求通常用于获取资源,在网页中,链接(<a>标签)、图像(<img>标签)、脚本(<script>标签)等元素都可以发起 GET 请求。
-
利用自动请求机制:
- 例如,使用<img>标签来发起攻击。攻击者在恶意网站上放置一个<img>标签,将其src属性设置为目标网站带有恶意操作的 GET 请求链接。当用户访问这个恶意网站时,浏览器会自动尝试加载这个图像,从而发送这个 GET 请求。
- 同样,对于<a>标签,攻击者可以设置href属性为恶意链接,然后通过一些手段(如欺骗用户点击看起来正常的链接)来让用户触发这个请求。不过这种方式相对比较容易被用户察觉,因为用户可能会看到链接的地址。
-
利用用户会话状态:就像其他类型的 CSRF 攻击一样,GET 型 CSRF 依赖于用户在目标网站的会话状态。当浏览器发送这个恶意的 GET 请求时,会自动带上用户在目标网站的会话 Cookie,目标网站收到请求后,由于有有效的会话标识,就可能会执行这个请求,以为是用户自己发起的操作。
3.示例
-
假设一个社交网站有一个点赞功能,其点赞的接口是https://social.com/like?post_id=123,正常情况下,用户点击社交网站上的点赞按钮会发送这个 GET 请求来为 ID 为 123 的帖子点赞。
-
攻击者在恶意网站上放置了这样的代码:
<img src="https://social.com/like?post_id=123" alt="malicious_image" />
-
当用户访问这个恶意网站时,浏览器会自动加载这个 “图像”,实际上就发送了一个点赞的 GET 请求。由于用户在社交网站的会话 Cookie 会被一起发送,社交网站就可能会为帖子 ID 为 123 的内容点赞,而用户对此可能完全不知情。
POST型CSRF
1.定义
POST 型 CSRF(Cross - Site Request Forgery)是一种跨站请求伪造攻击类型,它利用 HTTP POST 请求来实施攻击。攻击者通过诱导用户在已登录目标网站的状态下,在用户浏览器不知情的情况下发送包含恶意意图的 POST 请求,从而导致目标网站执行非用户本意的操作。
2.攻击流程
-
构造恶意表单:攻击者在恶意网站上构造一个包含目标网站恶意操作的表单。表单的action属性指向目标网站中执行关键操作的 URL,例如银行转账的提交 URL、用户信息修改的提交页面等。表单的各个字段则填写攻击者想要执行的操作参数,如转账金额、修改后的用户信息等。
-
自动提交表单或诱使用户提交:
-
攻击者可以使用 JavaScript 代码来自动提交表单。例如,在恶意 HTML 页面中有如下代码:
<form id="attackForm" action="https://target.com/transfer" method="post"> <input type="hidden" name="amount" value="1000" /> <input type="hidden" name="recipient" value="attacker_account" /> </form> <script> document.getElementById('attackForm').submit(); </script>
-
当用户访问这个恶意网站时,浏览器会自动提交这个表单,向目标网站发送一个 POST 请求。或者,攻击者也可以通过一些手段诱使用户手动提交表单,例如将提交按钮伪装成一个吸引人的链接或按钮,让用户在不知情的情况下点击。
-
-
利用用户会话状态:和 GET 型 CSRF 一样,POST 型 CSRF 也依赖于用户在目标网站的会话状态。当浏览器发送这个 POST 请求时,会自动带上用户在目标网站的会话 Cookie,目标网站收到请求后,由于收到了带有有效用户会话标识(Cookie)的请求,就会执行这个请求,以为是用户自己发起的操作。
三.防御措施
-
使用 CSRF 令牌(Token):
- 网站在生成表单或关键请求时,同时生成一个唯一的 CSRF 令牌并将其包含在表单中或者作为请求头的一部分。当服务器收到请求时,会验证这个令牌是否有效。因为攻击者无法轻易获取这个令牌,所以无法伪造有效的请求。
-
验证请求来源(Referer 检查):
- 服务器可以检查请求的来源(即Referer头信息),如果请求来自一个不可信的源,就拒绝这个请求。不过这种方法有一定的局限性,因为Referer头信息可以被浏览器插件或者用户自己修改。
-
Same - Site Cookie 属性设置:
- 可以将 Cookie 的Same - Site属性设置为Strict或者Lax。Strict模式下,浏览器只有在用户从同一站点访问时才会发送 Cookie;Lax模式稍微宽松一些,在一些安全的跨站导航场景下也允许发送 Cookie。这样可以限制 Cookie 在跨站请求中的滥用,从而减轻 CSRF 攻击的风险。