CSRF攻击

原理

  • 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
  • 在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
  • 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
  • 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
  • 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。

模拟

登录页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/login" method="post">
        账号:<input type="text" name="username">
        密码:<input type="password" name="password">
        <button type="submit">提交</button>
    </form>
</body>
</html>

转账接口

@RestController
public class AccountController {

    @PostMapping("/account/transfer")
    public String transfer(HttpSession session,String username, int money){
        String loginUser=(String)session.getAttribute("user");
        if(loginUser==null) {
            throw new IllegalStateException("用户为登录");
        }
        return loginUser+"向"+username+"转账"+money;
    }
    @PostMapping("/login")
    public String login(HttpSession session,String username, String password){
        session.setAttribute("user",username);
        return "登录成功";
    }
}

恶意页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
    </script>

</head>
<body>
    <form action="http://localhost:8080/account/transfer" method="post">
        <input type="text" name="username" value="zansan" hidden/>
        <input type="text" name="money" value="100" hidden/>
        <button type="submit">查看美女图片</button>
    </form>
</body>
</html>

在这里插入图片描述

流程总览

  1. 用户输入账号密码登录银行网站,服务器返回sessionID储存在cookie中
  2. 在未登出银行网站的情况下访问恶意网站
  3. 若点击链接则恶意网站会提交转账表单至银行网站,由于sessionID存储在cookie中,表单提交时也会携带cookie,服务器并不知道是恶意网站提交的表单,以为是该用户进行的操作,从而导致用户账户金额被转走。

防御措施

  • 同源检测
    HTTP头中有一个Referer字段,这个字段用以标明请求来源于哪个地址。在处理敏感数据请求时,通常来说,Referer字段应和请求的地址位于同一域名下。
  • token验证
    登录成功后,服务端生成一个token字段,以后客户端每次请求在请求头增加token字段,服务端拦截并验证是否携待token,若未携带,则视为csrf攻击
<body>
        账号:<input id="username" type="text" name="username">
        密码:<input id="password" type="password" name="password">
        <button id="btn">提交</button>

    <script type="text/javascript">
        $("#btn").click(function (){
            let username=$("#username").text();
            let password=$("#password").text();
            $.ajax({
                url:"/login",
                type:"post",
                xhrFields: {
                    withCredentials: true
                },
                data:{
                    "username":username,
                    "password":password
                },
                success:function (data) {
                    localStorage.setItem("user",data);
                }
            })
        })
    </script>
</body>


  • 表单增加随机数
    在表单中增加伪随机数字段,在验证表单时需验证是否匹配
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值