• ASP.NET Core 防止跨站请求伪造(XSRF/CSRF)攻击


    CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装成受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。

    这幅图已经能够很好地解释了跨站攻击是怎么回事,这样的网站很容易被别人钓鱼,

    示例:

    创建2个网站
    officialsite站点里有个 pay页面

    view:
          <h1>支付</h1>
          <form action="/pay/post" method="post">
              <input name="user" placeholder="姓名" />
              <input name="price" placeholder="金额" />
              <button type="submit">提交</button>
          </form>
    
    paycontroller:
            [HttpPost]
            public IActionResult Post(string user, decimal price)
            {
                return Json(new { ok = true, msg = $"{user}支付成功{price}元" });
            }
    

    FakeSite 站点里有个fakepay页面

    view:
        <h1>假的支付</h1>
        <form action="https://localhost:44316/pay/post" method="post">
            <input name="user" placeholder="姓名" />
            <input name="price" placeholder="金额" />
            <button type="submit">提交</button>
         </form>
    
    

    提交的请求并非自己站点 而是上一个站点的接口

    • 运行效果
    界面 运行效果
    点击提交后一样返回了上面网站的请求结果,这样官网就太危险了。

    那么asp.net core mvc里怎么处理?

    CSRF能够成功是因为在同一个浏览器中Cookies是共享的,也就无法通过cookies权限认证和验证来防止。
    解决的办法就是:要确保请求是自己的站点发出的就可以了,其他的站点发来的请求阻挡掉。
    通过AntiForgeryToken 在页面生成一个Token,发请求的时候把Token带上。处理服务端处理请求的时候需要验证这个Token。而其他站点没有这个token那么也就没法通过验证,就被阻挡了。

    • 继续改造上面的demo:
    <form action="/pay/post" method="post">
        @Html.AntiForgeryToken()
        <input name="user" placeholder="姓名" />
        <input name="price" placeholder="金额" />
        <button type="submit">提交</button>
    </form>
    
    F12看生成的html
    
    <h1>支付</h1>
    <form action="/pay/post" method="post">
        <input name="__RequestVerificationToken" type="hidden" value="CfDJ8Efjwr3EXZVEmlMrBkJrUWtWFC05YY78yz-ce3W4IjEE5m7SzISCXShbON9col2WEDQiqSuKJMbjnUV94a7nwO3O9YXHaFGJMl04AdDpviAGK8DidGgu9d7Gpbm8Zncd01AWL4v274emVQgJTabzPfo" />
        <input name="user" placeholder="姓名" />
        <input name="price" placeholder="金额" />
        <button type="submit">提交</button>
    </form>
    
    controller
     [ValidateAntiForgeryToken]
            [HttpPost]
            public IActionResult Post(string user, decimal price)
            {
                return Json(new { ok = true, msg = $"{user}支付成功{price}元" });
            }
    

    运行后界面一切正常

    接下来我们在取运行上一个伪造的站点,什么都不改,提交后就会提示返回400的错误

    这样就能搞定了。
    以上是表单提交,项目中常用的还是ajax请求,那该如何处理呢

    view:
    @inject Microsoft.AspNetCore.Antiforgery.IAntiforgery csrf
    <form action="/pay/post" method="post">
        @Html.AntiForgeryToken()
        <input name="user" placeholder="姓名" />
        <input name="price" placeholder="金额" />
        <button type="submit">提交</button>
        <button type="button" id="btnajax">ajax提交</button>
    </form>
    
     <script type="text/javascript">
            $(function () {
                $("#btnajax").click(function () {
                    $.ajax({
                        url: "/pay/post",
                        dataType: "text",
                        data: {
                            user: $("input[name=user]").val(),
                            price: $("input[name=price]").val()
                        },
                        headers: {
                            "RequestVerificationToken": '@csrf.GetAndStoreTokens(Context).RequestToken'
                        },
                        type: "post",
                        success: function (res) {
                            alert(res);
                        }
                    });
                })
            })
        </script>
    

    将ajax请求头里加上token,这样服务端就会校验。
    运行结果

    配置

    这个令牌验证还是需要借助cookie的
    配置 在setup里,可以根据需要去添加,比如需要验证的域名

      services.AddAntiforgery(options =>
                {
                    options.Cookie = new CookieBuilder { Domain = "company.com" };
                });
    

    demo代码见 github|

  • 相关阅读:
    SharePoint 2013 APP 开发示例 (六)服务端跨域访问 Web Service (REST API)
    麦咖啡导致电脑不能上网
    SharePoint 2013 Central Admin 不能打开
    SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)
    SharePoint 2013 APP 开发示例 系列
    synthesize(合成) keyword in IOS
    Git Cmd
    简单的正则匹配
    Dropbox
    SQL Server Replication
  • 原文地址:https://www.cnblogs.com/sands/p/10572059.html
Copyright © 2020-2023  润新知