二进制选手的web安全之路(0x2) : CSRF跨站请求伪造
字数 1034 2025-08-10 10:14:26

CSRF跨站请求伪造攻击详解

一、CSRF基本概念

CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种常见的Web安全漏洞。攻击者通过伪造用户的浏览器请求,向用户曾经认证过的网站发送请求,利用受害者尚未失效的身份认证信息(如cookie、会话等),在用户不知情的情况下以用户身份执行非法操作。

CSRF与XSS的区别

  • XSS:利用站点对用户输入的信任,注入恶意脚本窃取用户信息
  • CSRF:利用站点对用户浏览器的信任,伪造用户请求执行操作

二、DVWA Low级别CSRF漏洞分析

漏洞代码分析

<?php
if( isset( $_GET[ 'Change' ] ) ) {
    // 获取输入
    $pass_new = $_GET[ 'password_new' ];
    $pass_conf = $_GET[ 'password_conf' ];
    
    // 检查密码是否匹配
    if( $pass_new == $pass_conf ) {
        // 密码匹配
        $pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? 
                    mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new ) : 
                    ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
        
        $pass_new = md5( $pass_new );
        
        // 更新数据库
        $current_user = dvwaCurrentUser();
        $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . $current_user . "'";
        $result = mysqli_query($GLOBALS["___mysqli_ston"], $insert ) or die( '<pre>' . 
                    ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : 
                    (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
        
        // 用户反馈
        echo "<pre>Password Changed.</pre>";
    } else {
        // 密码不匹配
        echo "<pre>Passwords did not match.</pre>";
    }
    
    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>

漏洞点分析

  1. 使用GET请求处理敏感操作(密码修改)
  2. 没有任何CSRF防护措施(如token验证)
  3. 仅检查密码是否匹配,不验证请求来源

三、CSRF攻击实施步骤

1. 正常操作流程

  1. 用户登录目标网站
  2. 访问密码修改页面
  3. 输入新密码并确认
  4. 提交表单完成密码修改

2. 攻击者视角

  1. 构造恶意URL:
    http://target-site.com/vulnerabilities/csrf/?Change=1&password_new=123456&password_conf=123456
    
  2. 诱骗用户点击该链接(通过邮件、论坛、即时消息等)
  3. 用户点击时,浏览器会自动携带该网站的cookie发起请求
  4. 服务器误认为是用户合法操作,执行密码修改

3. 使用Burp Suite生成CSRF PoC

  1. 拦截正常密码修改请求
  2. 右键选择"Generate CSRF PoC"
  3. 在浏览器中测试生成的PoC

四、CSRF防御措施

1. 使用CSRF Token

  • 服务器生成随机token并存储在session中
  • 每次表单提交必须携带该token
  • 服务器验证token有效性

2. 检查Referer头部

  • 验证请求来源是否合法
  • 但Referer可能被浏览器禁用或伪造

3. 使用SameSite Cookie属性

  • 设置Cookie的SameSite属性为Strict或Lax
  • 防止跨站请求自动携带Cookie

4. 关键操作使用POST请求

  • 避免使用GET请求执行敏感操作
  • 虽然POST请求也可能被CSRF攻击,但难度更大

5. 二次验证

  • 对于敏感操作(如密码修改、转账等)要求二次验证
  • 如短信验证码、邮箱确认等

五、修复后的安全代码示例

<?php
if( isset( $_POST[ 'Change' ] ) ) {
    // 验证CSRF Token
    if( !isset( $_POST[ 'token' ] ) || $_POST[ 'token' ] != $_SESSION[ 'token' ] ) {
        die( 'Invalid CSRF Token' );
    }
    
    // 获取输入
    $pass_new = $_POST[ 'password_new' ];
    $pass_conf = $_POST[ 'password_conf' ];
    
    // 检查密码是否匹配
    if( $pass_new == $pass_conf ) {
        // 密码匹配
        $pass_new = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass_new);
        $pass_new = md5( $pass_new );
        
        // 更新数据库
        $current_user = dvwaCurrentUser();
        $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . $current_user . "'";
        $result = mysqli_query($GLOBALS["___mysqli_ston"], $insert ) or die( '<pre>' . 
                    mysqli_error($GLOBALS["___mysqli_ston"]) . '</pre>' );
        
        // 用户反馈
        echo "<pre>Password Changed.</pre>";
    } else {
        // 密码不匹配
        echo "<pre>Passwords did not match.</pre>";
    }
    
    mysqli_close($GLOBALS["___mysqli_ston"]);
}
?>

六、总结

CSRF攻击利用的是网站对用户浏览器的信任,防御的关键在于让服务器能够区分合法请求和伪造请求。通过结合CSRF Token、SameSite Cookie、请求方法限制等多种措施,可以有效防止CSRF攻击。开发者应特别注意不要使用GET请求执行敏感操作,并对所有可能改变系统状态的操作实施CSRF防护。

CSRF跨站请求伪造攻击详解 一、CSRF基本概念 CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种常见的Web安全漏洞。攻击者通过伪造用户的浏览器请求,向用户曾经认证过的网站发送请求,利用受害者尚未失效的身份认证信息(如cookie、会话等),在用户不知情的情况下以用户身份执行非法操作。 CSRF与XSS的区别 XSS :利用站点对用户输入的信任,注入恶意脚本窃取用户信息 CSRF :利用站点对用户浏览器的信任,伪造用户请求执行操作 二、DVWA Low级别CSRF漏洞分析 漏洞代码分析 漏洞点分析 使用GET请求处理敏感操作(密码修改) 没有任何CSRF防护措施(如token验证) 仅检查密码是否匹配,不验证请求来源 三、CSRF攻击实施步骤 1. 正常操作流程 用户登录目标网站 访问密码修改页面 输入新密码并确认 提交表单完成密码修改 2. 攻击者视角 构造恶意URL: 诱骗用户点击该链接(通过邮件、论坛、即时消息等) 用户点击时,浏览器会自动携带该网站的cookie发起请求 服务器误认为是用户合法操作,执行密码修改 3. 使用Burp Suite生成CSRF PoC 拦截正常密码修改请求 右键选择"Generate CSRF PoC" 在浏览器中测试生成的PoC 四、CSRF防御措施 1. 使用CSRF Token 服务器生成随机token并存储在session中 每次表单提交必须携带该token 服务器验证token有效性 2. 检查Referer头部 验证请求来源是否合法 但Referer可能被浏览器禁用或伪造 3. 使用SameSite Cookie属性 设置Cookie的SameSite属性为Strict或Lax 防止跨站请求自动携带Cookie 4. 关键操作使用POST请求 避免使用GET请求执行敏感操作 虽然POST请求也可能被CSRF攻击,但难度更大 5. 二次验证 对于敏感操作(如密码修改、转账等)要求二次验证 如短信验证码、邮箱确认等 五、修复后的安全代码示例 六、总结 CSRF攻击利用的是网站对用户浏览器的信任,防御的关键在于让服务器能够区分合法请求和伪造请求。通过结合CSRF Token、SameSite Cookie、请求方法限制等多种措施,可以有效防止CSRF攻击。开发者应特别注意不要使用GET请求执行敏感操作,并对所有可能改变系统状态的操作实施CSRF防护。