当前位置: 首页 > news >正文

网络安全 | 深入解析CSRF攻击与防御实战

关注: CodingTechWork

引言

  Cross-Site Request Forgery(CSRF)是一种冒充用户执行非预期操作的攻击方式,它在OWASP Top 10中曾长期占有一席之地。本文将深入剖析CSRF,并通过Java代码示例,展示如何构建坚固的CSRF防线。

CSRF介绍

  CSRF(跨站请求伪造),也被称为“One-Click Attack”或“Session Riding”。它是一种诱骗已认证用户在不知情的情况下,运行一个恶意Web应用程序操作的攻击。
  核心危害:攻击者并不能直接窃取你的Cookie或会话数据,而是利用你的浏览器对目标网站的已认证状态,以你的名义执行恶意操作,如修改密码、转账、发布内容等。

CSRF攻击类似的流程

  • 你已登录网上银行(相当于在银行大厅办理业务)。
  • 攻击者给你一个精心设计的链接(相当于递给你一张伪造的“转账授权书”)。
  • 你点击了链接,浏览器自动携带你的登录凭证(Cookie)向银行发起转账请求(相当于你在不知情的情况下签署了授权书)。
  • 银行看到是你的凭证,便执行了操作。

CSRF攻击的原理与产生条件

核心原理

  利用浏览器的同源策略不会阻止向目标网站发送请求的机制,并自动携带用户的认证信息(如Session Cookie)。

必要条件

  1. 用户已登录目标网站(A站),并且会话(Session)未过期。
  2. 用户访问了恶意网站(B站),该网站包含一个自动向A站发起请求的代码。
  3. 目标网站(A站)完全依赖Cookie(通常是Session Cookie)来认证用户身份,没有其他机制来验证请求的意图。
  4. 请求是可预测的,攻击者能构造出执行特定操作所需的请求参数。

一个CSRF攻击是如何发生的?

假设有一个Java Web应用,提供一个修改用户邮箱的GET接口(注意:使用GET进行状态变更操作本身就是不安全的)。

1. 易受攻击的Java Servlet

// 危险的Servlet:使用GET方法执行敏感操作,且无CSRF防护
@WebServlet("/changeEmail")
public class ChangeEmailServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1. 从Session中验证用户登录状态HttpSession session = request.getSession(false);if (session != null && session.getAttribute("user") != null) {// 2. 用户已登录,执行修改邮箱操作String newEmail = request.getParameter("newEmail");User user = (User) session.getAttribute("user");userService.updateEmail(user.getId(), newEmail); response.getWriter().write("Email updated successfully!");} else {response.sendError(HttpServletResponse.SC_UNAUTHORIZED);}}
}

2. 攻击者构造的恶意页面(malicious-site.com)

<!DOCTYPE html>
<html>
<head><title>看起来无害的页面</title>
</head>
<body><h1>来看一张有趣的图片!</h1><!-- 利用img标签的src属性自动发起GET请求 --><img src="http://your-java-app.com/changeEmail?newEmail=hacker@evil.com" width="0" height="0" alt="Fake Image" /><p>(实际上,页面在后台悄悄修改了你在“your-java-app.com”的邮箱)</p><script>// 或者使用JavaScript自动提交一个隐藏的表单(对POST请求同样有效)setTimeout(function() {document.getElementById('csrf-form').submit();}, 100);</script><!-- 隐藏的表单,用于模拟POST请求 --><form id="csrf-form" action="http://your-java-app.com/changeEmail" method="POST" style="display:none;"><input type="hidden" name="newEmail" value="hacker@evil.com" /></form>
</body>
</html>

攻击流程

  1. 用户登录了 http://your-java-app.com,Session有效。
  2. 用户随后访问了 http://malicious-site.com
  3. 恶意页面中的 <img> 标签或JavaScript会自动向 your-java-app.com 发起请求(携带用户的Session Cookie)。
  4. 你的Java应用收到请求,验证Session有效,于是执行了修改邮箱的操作。

如何在Java世界中防御CSRF?

防御CSRF的核心思想是:增加一个攻击者无法预测且无法伪造的额外验证凭证

1. 使用Anti-CSRF Token(同步器令牌模式)

原理:在用户会话中存储一个随机、不可预测的Token(令牌)。在渲染表单时,将此Token作为一个隐藏字段放入表单。当表单提交时,服务器验证提交的Token是否与会话中存储的Token一致。

2. 使用Spring Security

如果你使用Spring框架,Spring Security默认就提供了强大且开箱即用的CSRF防护

  • 默认行为:Spring Security会为每个Session生成一个CSRF Token,并期望在所有非GET、HEAD、TRACE、OPTIONS的请求(如POST, PUT, PATCH, DELETE)中携带一个名为_csrf的参数或X-CSRF-TOKEN头。
  • 与Thymeleaf集成:在Thymeleaf模板中,只需在表单中添加th:action,Thymeleaf会自动帮你插入CSRF Token隐藏域。
    <form th:action="@{/changeEmail}" method="post"><input type="email" name="newEmail"><button type="submit">更新邮箱</button><!-- Thymeleaf会自动生成:<input type="hidden" name="_csrf" value="..."> -->
    </form>
    
  • 自定义与禁用:如果需要为某些接口(如API)禁用CSRF,可以在配置中操作
    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authz -> authz.anyRequest().authenticated()).csrf(csrf -> csrf// 忽略某些API路径,例如/webhook(风险自担)// .ignoringRequestMatchers("/webhook/**"));return http.build();}
    }
    

3. 验证SameSite Cookie

为Cookie设置SameSite属性可以作为一种有效的深度防御措施。

  • SameSite=Strict:最严格,完全禁止第三方Cookie。
  • SameSite=Lax:(默认值)在大多数跨站导航(如从外站链接点击过来)时发送Cookie,但不会在跨站的POST请求或图像加载中发送。
  • SameSite=None:允许跨站发送,但必须同时设置Secure属性(HTTPS)。

web.xml或Servlet中配置:

<session-config><cookie-config><http-only>true</http-only><!-- 仅HTTPS --><secure>true</secure> <!-- 或 strict --><same-site>lax</same-site></cookie-config>
</session-config>
http://www.dtcms.com/a/618333.html

相关文章:

  • 动态网站发布部署核心问题详解
  • 基于RTT调试接口的项目适配性的lib库化实现与工程应用
  • 解决Blender新加面后不跟随骨骼移动(骨骼权重的绘制)
  • 深圳光明网站建设今天福州发生的重大新闻
  • Android 自定义「阶段进度条(步轴)」实践
  • 【第三阶段-核心功能开发:UI进阶】第七章:主题系统-就像室内设计师
  • discuz 手机网站wordpress 搜索自定义数据表字段
  • CC++链接数据库(MySQL)超级详细指南
  • 苍穹外卖 —— 数据统计和使用Apache_POI库导出Excel报表
  • 昆明好的网站制作网站价格评估 优帮云
  • 如何查询SQL Server数据库服务器的IP地址
  • 开源:开源协议从入门到落地
  • 网站域名要怎样规划佛山做外贸网站案例
  • 网站建设找导师蓝林月租网站空间
  • 2025 IntelliJ IDEA 2025最新免费安装教程
  • Numpy数值分析库实验
  • 游戏常用运行库丨免费纯净丨多系统支持丨自动推荐安装
  • git-拉取代码报错update ref failed ref ‘ORIG HEAD‘
  • 手机网站模板 html5西安搬家公司电话号码大全
  • 资源优化排名网站哈尔滨企业网站模板建站
  • 基于扩散模型与流模型的跨分辨率流场映射方法研究
  • 【Linux日新月异(十)】CentOS 7 文件系统结构深度解剖:从根到叶的完整指南
  • linux服务-rsync+inotify文件同步-ssh
  • 保障房建设网站首页游戏策划
  • 深度学习杂草分割系统1:数据集说明(含下载链接)
  • 超分辨率重建(Super-Resolution, SR)
  • 高端品牌网站建设注意事项制作ppt的基本做法
  • 2025 年 Redis 面试天花板
  • component-富文本实现(WangEditor)
  • 烟台城乡住房建设厅网站网站alt标签