• asp.netcore mvc 防CSRF攻击,原理介绍+代码演示+详细讲解


    一、CSRF介绍

    1.CSRF是什么?

      CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。

    2.CSRF可以做什么?

    你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。

    3.CSRF漏洞现状

      CSRF这种攻击方式在2000年已经被国外的安全人员提出,但在国内,直到06年才开始被关注,08年,国内外的多个大型社区和交互网站分别 爆出CSRF漏洞,如:NYTimes.com(纽约时报)、Metafilter(一个大型的BLOG网站),YouTube和百度HI......而 现在,互联网上的许多站点仍对此毫无防备,以至于安全业界称CSRF为“沉睡的巨人”。

    4.CSRF的原理

    从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成两个步骤:

      1.登录受信任网站A,并在本地生成Cookie。

      2.在不登出A的情况下,访问危险网站B。

      看到这里,你也许会说:“如果我不满足以上两个条件中的一个,我就不会受到CSRF的攻击”。是的,确实如此,但你不能保证以下情况不会发生:

      1.你不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站。

      2.你不能保证你关闭浏览器了后,你本地的Cookie立刻过期,你上次的会话已经结束。(事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了......)

      3.上图中所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。

    二、ASP.NETCORE MVC 防CSRF

    前端采用的是 elmentui+vue.js

    1.前端html:

    @{
        Layout = null;
    }
    <link href="~/lib/element-ui/theme-chalk/index.css" rel="stylesheet" />
    <link href="~/css/common.css" rel="stylesheet" />
    <style>
        .el-header {
            background-color: aliceblue;
            color: lightcyan;
            line-height: 800px;
        }
    </style>
    @Html.AntiForgeryToken()
    <!--
    asp.netcore mvc前端页面加上 @Html.AntiForgeryToken() 方法,这个方法会生成一个隐藏域
    <input name="__RequestVerificationToken" type="hidden" value="7FTM...sdLr1" />,
    原理请查看本文后面的说明。
    -->
    <div id="app"> <el-form :model="addForm.data" status-icon :rules="addRules" ref="addData" label-width="100px" class="demo-ruleForm"> <el-form-item label="账号" prop="account"> <el-input style="300px" v-model="addData.account"></el-input> </el-form-item> <el-form-item label="名称" prop="name"> <el-input style="300px" v-model="addData.name"></el-input> </el-form-item> <el-form-item label="密码" prop="password"> <el-input style="300px" type="password" v-model="addData.password" autocomplete="off"></el-input> </el-form-item> <el-form-item label="确认密码" prop="checkpassword"> <el-input style="300px" type="password" v-model="addData.checkpassword" autocomplete="off"></el-input> </el-form-item> <el-form-item label="是否启用" prop="isEnabled"> <el-switch v-model="addData.isEnabled"></el-switch> </el-form-item> <el-form-item> <el-button type="primary" @@click="saveData('addForm')">保存</el-button> <el-button @@click="resetForm('addForm')">重置</el-button> </el-form-item> </el-form> </div>

    2.前端JS脚本:

    new Vue({
        el: "#app",
        data:{
             //新增表单数据
           addData: {
             account: '',
             name: '',
             password: '',
             checkpassword: '',
             isEnabled: false,
           },
    token:"",
    },
    //挂在模板之后调用
      
    mounted() {
      //获取防 CSRF 攻击token
      this.token = document.getElementsByName("__RequestVerificationToken")[0].value;
       },
        methods:{
                saveData:function(){
                     var data = new FormData();
                }
        },
       saveData: function (formName) {
          
    var data = new FormData(); data.append("__RequestVerificationToken", this.token);//需要通过 FormData表单来传递 @Html.AntiForgeryToken() data.append("account", this.addData.account); data.append("name", this.addData.name); data.append("password", this.addData.password); data.append("checkpassword", this.addData.checkpassword); data.append("isEnabled", this.addData.isEnabled); var url = "/UserManagement/AddUser"; axios.post(url, data).then(response => { //必须使用 post请求 var data = response.data; //todu-----------
    }).
    catch(() => {
    //todu--------
    });
         }
    })

     3.后台代码拦截:

    //[ValidateAntiforgeryToken]  会拦截 前端传递过来的token,并进行比对,比对通过,则允许访问,否则不允许。
    //ValidateAntiforgeryToken 只对 httppost请求生效,因此必须将action 限定为httppost请求
    [HttpPost]
    [ValidateAntiforgeryToken]
    public async Task<ResultDTO> AddUser(UserAddDTO dto)
     {
          if (!ModelState.IsValid)
                throw new KMException("请按要求填写数据");
           return await _userInfoBLL.AddUser(dto, UserAccount);
     }

    @Html.AntiForgeryToken() 防CSRF说明:

    1.在CSHtml 页面中,@Html.AntiForgeryToken() 方法会生成 一个隐藏域  <input name="__RequestVerificationToken" type="hidden" value="7FTM...sdLr1" />

    2.前端JS里,将获取到的CSHtml 隐藏域 的token,通过表单FormData 传递给 后台 Action(注意,只能通过FormData来传递,而且必须使用post请求

    3.后台 Action 的 [ValidateAntiforgeryToken] 属性,会拦截前端传递过来的 token,并进行比对,通过则允许访问,否则不允许。注意,ValidateAntiforgeryToken 只对 httppost请求生效,因此必须将action 限定为httppost请求

    本文参考:https://blog.csdn.net/sunstar8921/article/details/81974071

  • 相关阅读:
    LeetCode 腾讯精选50题--求众数
    LeetCode 腾讯精选50题--只出现一次数字
    LeetCode 腾讯精选50题--链表排序
    LeetCode 腾讯精选50题--子集
    LeetCode 腾讯精选50题-- 买卖股票的最佳时机 II
    LeetCode 腾讯精选50题--合并K个排序链表
    AspNet Core 下利用普罗米修斯+Grafana构建Metrics和服务器性能的监控 (无心打造文字不喜勿喷谢谢!)
    Javascript 堆栈的模拟
    React使用Mobx管理数据
    如何在.Net Core调用NodeJs
  • 原文地址:https://www.cnblogs.com/Fengyinyong/p/13039771.html
Copyright © 2020-2023  润新知