CSRF 的攻击与防御

目录

CSRF 的攻击与防御

一、CSRF 的原理

二、CSRF 的场景和易受攻击的业务

三、CSRF 与 XSS 的危险性比较

四、CSRF 的最佳利用方式

五、防御措施

(一)后端 Java 代码示例

(二)前端 Vue 代码示例


在 Web 应用安全领域,CSRF(Cross - Site Request Forgery)攻击是一种常见且具有潜在危害的安全威胁。它往往涉及个人隐私泄露以及财产安全问题。本文将详细介绍 CSRF 的原理、场景、业务易受攻击性以及相应的防御措施,并提供前端 Vue 和后端 Java 的代码示例。

一、CSRF 的原理

由于浏览器的特性,会自动携带同一域名下的 Cookie 到服务器。服务器端的某些功能在验证了 Cookie 有效性后,就会执行相应功能。这就使得攻击者有可能利用用户的身份,在用户不知情的情况下,以用户的名义发送恶意请求。

二、CSRF 的场景和易受攻击的业务

  1. 场景分类
    • 包括修改个人数据(横向越权),例如攻击者可能会修改用户的个人信息,如联系方式、收货地址等;添加用户(纵向越权)等情况。
  2. 易受攻击的业务类型
    • CSRF 一般用于操作用户的资源,或者使用用户的权限进行操作,或者窃取用户的相关信息。常见的如电商业务中的订单操作、社交网络中的信息发布(如发微博)、用户账号授权相关的操作(如二维码登陆、绑定第三方账号等)。

三、CSRF 与 XSS 的危险性比较

对于 CSRF 是否比 XSS 更具危险性,存在不同观点。有人认为 CSRF 不比 XSS 更有危险性,因为 CSRF 能完成的事,XSS 更能够完成;而 XSS 能完成的事,CSRF 不一定能做到。

四、CSRF 的最佳利用方式

CSRF 可用于多种敏感操作,例如给电商用户新增默认收货地址、发微博、添加管理员等等。所有的敏感操作都可能成为攻击目标,因此都需要进行 CSRF 的防护。

五、防御措施

(一)后端 Java 代码示例

  1. 使用 Token 验证
    • 在 Java 后端,可以为每个用户会话生成一个唯一的 Token,并在敏感操作的请求中包含该 Token。服务器端验证请求中的 Token 是否与用户会话中的 Token 一致。以下是一个简单的示例:

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;

public class CSRFTokenUtil {
    public static String generateToken() {
        return UUID.randomUUID().toString();
    }

    public static void setTokenCookie(HttpServletResponse response) {
        String token = generateToken();
        Cookie cookie = new Cookie("csrf_token", token);
        cookie.setPath("/");
        response.addCookie(cookie);
    }

    public static boolean validateToken(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if (cookies!= null) {
            for (Cookie cookie : cookies) {
                if ("csrf_token".equals(cookie.getName())) {
                    String requestToken = request.getParameter("csrf_token");
                    return cookie.getValue().equals(requestToken);
                }
            }
        }
        return false;
    }
}

在上述代码中,generateToken方法用于生成一个随机的 Token,setTokenCookie方法用于将 Token 设置为一个 Cookie 发送给客户端,validateToken方法用于验证请求中的 Token 是否有效。

  1. Referer 限制
    • 可以对请求的 Referer 进行校验。但要注意严格校验 host,而不是简单的使用一个字符包含的检查。以下是一个简单的示例,用于检查 Referer 是否来自合法的域名:

import javax.servlet.http.HttpServletRequest;

public class RefererValidator {
    public static boolean validateReferer(HttpServletRequest request) {
        String referer = request.getHeader("Referer");
        if (referer!= null) {
            // 假设合法域名是example.com
            return referer.contains("example.com");
        }
        return false;
    }
}

  1. 日志系统
    • 建立严格的日志系统也是一种重要的防护手段。通过记录请求信息,可以在事后甄别一定的 CSRF 攻击。例如,可以使用 Java 的日志框架(如 Log4j)来记录请求的相关信息:

import org.apache.log4j.Logger;

public class CSRFLogger {
    private static final Logger logger = Logger.getLogger(CSRFLogger.class);

    public static void logRequest(HttpServletRequest request) {
        logger.info("Request URL: " + request.getRequestURL());
        logger.info("Referer: " + request.getHeader("Referer"));
        logger.info("Parameters: " + request.getParameterMap());
    }
}

(二)前端 Vue 代码示例

  1. 使用 Token 验证(结合后端)
    • 在 Vue 前端,可以在发送敏感请求时,从 Cookie 中获取 Token 并添加到请求参数中。以下是一个简单的示例:

<template>
  <div>
    <button @click="sendSensitiveRequest">发送敏感请求</button>
  </div>
</template>

<script>
export default {
  methods: {
    sendSensitiveRequest() {
      const csrfToken = document.cookie.match(/csrf_token=(.*?);/)[1];
      // 假设这里是一个axios请求,用于发送敏感请求
      axios.post('/sensitive-api', { csrf_token: csrfToken })
      .then(response => {
          console.log(response);
        })
      .catch(error => {
          console.log(error);
        });
    }
  }
};
</script>

在上述代码中,当点击按钮时,会从 Cookie 中获取csrf_token并添加到 POST 请求的参数中,发送到后端的/sensitive-api接口。

  1. 校验 X - Requested - With 头(针对 Ajax 请求)
    • 如果请求仅仅是 Ajax 请求,那么可以校验X - Requested - With头。以下是一个简单的示例,用于在 Vue 中发送 Ajax 请求并校验该请求头:

<template>
  <div>
    <button @click="sendAjaxRequest">发送Ajax请求</button>
  </div>
</template>

<script>
export default {
  methods: {
    sendAjaxRequest() {
      const xhr = new XMLHttpRequest();
      xhr.open('POST', '/ajax-api');
      xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
          console.log(xhr.responseText);
        }
      };
      xhr.send();
    }
  }
};
</script>

在上述代码中,在发送 Ajax 请求时,设置了X - Requested - With头为XMLHttpRequest,并且在服务器端可以校验该请求头,以防止 CSRF 攻击。

希望通过对 CSRF 攻击与防御的这些介绍,能让开发人员和用户更加重视 CSRF 问题,采取有效的措施来保障 Web 应用的安全。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值