CSRF 攻击是一种常见且危险的 Web 安全漏洞,攻击者可以通过伪造用户请求,执行恶意操作,这篇文章,我们将一起分析什么是 CSRF?CSRF是如何工作的?以及我们该如何预防 CSRF?
什么是 CSRF?
CSRF,全称 Cross-Site Request Forgery,中文翻译为跨站请求伪造,它是一种网络安全漏洞,攻击者通过伪造用户的请求,利用用户在已登录的情况下的身份验证信息,向服务器发送恶意请求,从而执行未经用户授权的操作。
CSRF攻击通常发生在用户已经登录了某个网站的情况下,攻击者在用户不知情的情况下利用用户的身份信息发送恶意请求,导致服务器误以为是用户发送的合法请求。
如下图所示,CSRF攻击大致由两部分组成:
- 跨站点:用户登录到一个网站,并且被骗点击了攻击者构建的另一个网站链接,这代表了 CSRF 的“跨站点”部分。
- 请求伪造:当受害者用户在同一浏览器中打开链接时,会向该网站发送一个伪造的请求,其中包含攻击者设置的值以及受害者与该网站关联的所有 cookie。
CSRF 如何工作?
CSRF攻击一般是按照下面 2个步骤进行:
- 利用会话Cookie
- 构造CSRF攻击
利用会话Cookie
CSRF攻击会利用了会话cookie,该 cookie在浏览器和服务器之间共享,由于 HTTP请求是无状态的,因此服务器无法区分浏览器发送的两个请求。
但是有许多情况下,我们希望服务器能够将一个 HTTP请求与另一个相关联。例如,登录请求后跟随的请求来检查账户余额或转账,只有在登录请求成功后,服务器才会允许这些请求,我们将这些请求组称为会话。
使用Cookie来保存会话信息,服务器将特定客户端的会话信息打包到一个cookie中,并将其发送到客户端的浏览器。对于每个新请求,浏览器通过将cookie(带有会话密钥)发送回服务器来重新识别自己。
攻击者劫持(或利用)这个cookie,以欺骗用户将攻击者构建的请求发送到服务器。
构造 CSRF攻击
攻击者构造 CSRF攻击的广泛步骤序列包括以下步骤:
- 识别和探索易受攻击的网站,以寻找可以利用的感兴趣的功能(诱饵)
- 创建CSRF攻击 URL
- 诱导点击 URL
接下来,我们再更详细地了解每个步骤。
识别和探索易受攻击的网站
在计划 CSRF攻击之前,攻击者需要识别感兴趣的功能,例如资金转账。攻击者还需要了解网站中的一个有效 URL,以及 URL接受的有效请求模式,此 URL应导致目标应用程序中的状态更改操作。
常见的一些状态更改操作示例如下:
- 更新账户余额
- 创建客户记录
- 转账
与状态更改操作相反,查询不会在服务器中更改任何状态。例如,查看用户资料,查看账户余额等不会在服务器中更新任何内容。
攻击者还需要找到 URL参数的正确值,否则,目标应用程序可能会拒绝伪造的请求。
用于探索易受攻击网站的一些常见技术包括:
- 查看HTML源代码:检查网页的HTML源代码,以识别包含感兴趣功能的链接或按钮。
- Web应用程序调试工具:使用 WebScarab、Tamper Dev等 Web应用程序调试工具分析客户端和服务器之间交换的信息。
- 网络嗅探工具:使用网络嗅探工具(如 Wireshark)分析客户端和服务器之间交换的信息。
例如,假设攻击者已经识别了一个网站 yuanjava.com 来尝试 CSRF攻击,攻击者使用上述技术探索了这个网站,并发现了一个带有CSRF漏洞的 URL yuanjava.com/account 用于转账。
创建CSRF攻击 URL
攻击者接下来将尝试构建一个用于与受害者共享的攻击 URL,假设应用程序中的转账功能使用 POST方法,向另一个账户(账号为6666)转账 100元,合法请求将如下所示:
POST https://yuanjava.com/account?amount=100&accountNumber=6666
攻击者将创建一个攻击 URL,将 15000元转账给另一个可疑账户(账号为8888),URL:https://yuanjava.com/account?amount=15000&accountNumber=8888
当受害者点击这个攻击 URL,15000元将被转账到攻击者的账户(账号为8888)。
诱导点击 URL
创建了攻击 URL后,攻击者还必须欺骗受害者用户点击它,为此,攻击者创建了一种诱导,并使用任何社会工程攻击方法欺骗受害者用户点击恶意URL。
常见的诱导方式有:
- 将攻击URL包含在HTML图像元素中
- 将攻击URL放在受害者用户经常在登录应用程序时访问的页面上
- 通过电子邮件发送攻击 URL
如何防御 CSRF 攻击?
为了防御 CSRF 攻击,可以采用以下几种常见的策略:
- 使用 CSRF Token:在表单提交时,加入一个随机生成的唯一 token,并在服务器端进行验证,只有包含正确 token 的请求才被认为是合法的。
- 检查 Referer 或 Origin 头:通过检查请求头中的 Referer 或 Origin 字段,确保请求来源于受信任的页面。
- SameSite Cookie 属性:将 Cookie 的 SameSite 属性设置为 Strict 或 Lax,限制跨站点请求携带 Cookie。
- 双重提交 Cookie:在每个请求中,同时通过 Cookie 和请求参数提交一个相同的 token,服务器端验证两者是否一致。
- 安全部门或者购买安全云产品
如下代码示例,在 Java层创建一个配置类,启用 CSRF 保护:
import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; public class SecurityConfig extends WebSecurityConfigurerAdapter { protected void configure(HttpSecurity http) throws Exception { http.csrf().and().authorizeRequests().antMatchers("/").permitAll().anyRequest().authenticated(); } }
解释说明:
- Spring Security CSRF Token:Spring Security 默认启用了 CSRF 保护。在我们创建的 SecurityConfig 类中,http.csrf().and() 部分启用了 CSRF 保护。Spring Security 会自动生成一个 CSRF Token,并在每个请求中进行验证。
- 表单中的 CSRF Token:在 form.html 文件中, 部分插入了 CSRF Token。Spring Security 提供了一个 _csrf 对象,其中包含了 parameterName 和 token,分别表示 CSRF Token 的参数名和值。
- CSRF Token 验证:当请求提交时,Spring Security 会验证请求中的 CSRF Token。如果验证失败,将返回 403 Forbidden 错误。
总结
CSRF 攻击是一种常见且危险的 Web 安全漏洞,攻击者可以通过伪造用户请求,执行恶意操作,作为程序员,为了防御 CSRF 攻击,常见的策略包括使用 CSRF Token、检查 Referer 或 Origin 头、设置 SameSite Cookie 属性以及双重提交 Cookie。
因为程序员对于 CSRF 攻击可以做的事情还是很有限,所以,承担主要责任的是安全部门或者运维部门,但是作为程序员,我们需要具备这些安全意识,在安全等级比较高的需求中也需要把这些安全因素考虑在内。