文章详情
关于CSRF攻击简介
Posted on 2017-02-01 12:17:36 by 主打一个C++
CSRF(跨站请求伪造,Cross-Site Request Forgery)是一种常见的网络安全攻击方式。
攻击者会诱导用户在已登录的可信网站上执行非预期的操作。
这种攻击利用了受害者的身份认证信息(如cookie中的session信息),在用户不知情的情况下,向受害者的网站发送请求。
例如:攻击者可以在一个恶意网站上设置一个链接或表单,诱导已登录银行网站的用户点击或提交。
如果用户的浏览器中还保存着银行网站的session信息,那么这个请求就会被视为来自受害者的合法请求,
从而在银行网站上执行相应的操作,如转账等。
为了防止这种攻击,网站通常会采用一些防护措施,比如使用CSRF令牌(token)、验证请求来源(Referer检查)等方法。
以下为防止攻击的例子:
1.测试表单
<?php
session_start();
// 检查是否已经有CSRF令牌,如果没有则生成一个
if (!isset($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
$csrf_token = $_SESSION['csrf_token'];
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>CSRF示例表单</title>
</head>
<body>
<h1>请提交表单</h1>
<form action="process.php" method="post">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrf_token); ?>">
<label for="name">姓名:</label>
<input type="text" id="name" name="name" required><br><br>
<label for="email">电子邮件:</label>
<input type="email" id="email" name="email" required><br><br>
<input type="submit" value="提交">
</form>
</body>
</html>
2.测试验证表单
<?php
session_start();
// 检查是否接收到CSRF令牌,或者直接使用$_SESSION['csrf_token']比较即可
if (!isset($_POST['csrf_token'])) {
die('CSRF令牌丢失');
}
// 验证接收到的CSRF令牌是否与会话中的令牌匹配
$received_token = $_POST['csrf_token'];
if (!hash_equals($_SESSION['csrf_token'], $received_token)) {
die('CSRF令牌验证失败');
}
// 如果验证通过,继续处理表单数据
$name = htmlspecialchars($_POST['name']);
$email = htmlspecialchars($_POST['email']);
// 这里可以添加对$name和$email的进一步处理,比如保存到数据库
echo "姓名: " . $name . "<br>";
echo "电子邮件: " . $email;
// 处理完成后,可以重置或更新CSRF令牌
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
?>
原理:
生成CSRF令牌:在用户访问表单页面时,检查会话中是否存在CSRF令牌,如果不存在则生成一个新的令牌并存储在会话中。
在表单中包含CSRF令牌:将生成的CSRF令牌作为隐藏字段包含在表单中,使得在提交表单时可以一起发送这个令牌。
验证CSRF令牌:在处理表单提交的页面中,首先检查并验证接收到的CSRF令牌是否与会话中的令牌匹配。如果不匹配,则拒绝处理该请求。
重置或更新CSRF令牌:处理完表单数据后,为了防止重放攻击,可以重置或更新会话中的CSRF令牌。
这种方法可以有效地防止CSRF攻击。