• 跨站请求伪造(CSRF)-简述


    跨站请求伪造(CSRF)-简述

    跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。[1] 跟跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。(维基百科)

    当我们请求一个目标网站时,浏览器会发送该目标网站相关的cookie信息。当我们浏览其他的网站时,如果我们没有退出该目标网站,而其他的网站有一个向目标网站的操作链接,这时因为我们在线,且有cookie信息,那么目标网站就会认为这是一个合法的请求而执行。但是这个操作不是我们自己请求的,而是恶意者用我们自己被认证过的身份执行的操作。

    这种恶意的网址并不需要一个特定的网站,它可以藏身在任何一个由用户生成内容的网站中,如论坛,博客等。

    如果有账户名为Alice的用户访问了恶意站点,而她之前刚访问过在线交易网站,登录信息尚未过期,那么她就会损失1000资金。

    Get方式攻击:

    假设一个在线交易网站有一个转账的url:

    http://www.examplebank.com/withdraw?account=AccoutName&amount=1000&for=PayeeName
    

    一个恶意者在另一个网站添加了如下代码

    <img src="http://www.examplebank.com/withdraw?account=Alice&amount=1000&for=Badman">
    

    Post方式攻击:

    //目标网站的form
    <form id="form" action="withdraw/trans" method="post">
        <input name="account" type="text"/>
        <input name="amount" type="text"/>
        <input name="forAccount" type="text"/>
    </form>
    

    恶意链接

    //指向恶意Html的链接
    <img src="http://other/maliciouspage.html"/>
    

    恶意html:

    <html>
     <head>
           <script type="text/javascript">
             window.onload = function () {
                 document.myform.submit(); 
             }
             </script>
     </head>
     <body>
        <form id="myform" name="myform" action="withdraw/trans" method="post"/>
            <input name="account" type="hidden" value="Alice" />
            <input name="amount" type="hidden" value="1000"/>
            <input name="forAccount" type="hidden" value="Badman"/>
        </form>
    </body>
    </html>
    

    恶意Html部署在http://other/maliciouspage.html。恶意链接在任何一个可以由用户生成内容的网站,当有用户是Alice浏览到一个有恶意链接的网站时,就会加载恶意html,执行form方法。


    @Html.AntiForgeryToken

    如何避免这个恶意请求呢?

    既然浏览器是不可信的,那么就用一个非浏览器的而是跟页面自身(用户唯一)才有的唯一随机值作为验证对象。

    @Html.AntiForgeryToken的验证流程:

    生成验证值:

    1. 当在View中调用AntiForgeryToken时会先生成一个cookie的名称,该名称的前缀为"_RequestVerificationToken"。

    2. 如果当前的请求中已有该cookie,则直接对该cookie的值进行序列化(包含加密解密操作)得到AntiForgeryData对象。如果没有该cookie则生成一个AntiForgeryData对象。

    3. 创建cookie,名称为1中生成的值,值为2中AntiForgeryData对象解析后的字符串(前后值会不一样,因为还有其他的随机值作为解析参数)。

    4. @Html.AntiForgeryToken会生成一个名为"_RequestVerificationToken"的隐藏控件,该控件的值是根据现有的AntiForgeryData对象再创建一个新的AntiForgeryData对象,序列化的字符串。

    匹配验证值:

    1. 在form提交时,服务端会先根据之前生成cookie的逻辑再次获取到cookie名称,如果没有找到对应cookie就抛出异常,如果找到该cookie,就解析解密为AntiForgeryToken对象。

    2. 然后在表单中查找名称为"_RequestVerificationToken"的控件,没有找到抛出异常,找到的话该控件的值解析解密为AntiForgeryToken对象.

    3. 隐藏控件中的AntiForgeryToken和cookie解析解密的AntiForgeryToken对象匹配,一致为合法,不一致为非法。

    因为@Html.AntiForgeryToken的值是随机且加密的,所以恶意html的表单里很难获取到正确的值。

    Cookie:

        HTTP/1.1 200 OK
        Cache-Control: private
        Set-Cookie: __RequestVerificationToken_L012Y0FwcDEx=EYPOofprbB0og8vI+Pzr1unY0Ye5BihYJgoIYBqzvZDZ+hcT5QUu+fj2hvFUVTTCFAZdjgCPzxwIGsoNdEyD8nSUbgapk8Xp3+ZD8cxguUrgl0lAdFd4ZGWEYzz0IN58l5saPJpuaChVR4QaMNbilNG4y7xiN2/UCrBF80LmPO4=; path=/; HttpOnly
    

    Form:

     <form action="..." method="post">
    <input name="__RequestVerificationToken" type="hidden" value="yvLaFQ81JVgguKECyF/oQ+pc2/6q0MuLEaF73PvY7pvxaE68lO5qgXZWhfqIk721CBS0SJZjvOjbc7o7GL3SQ3RxIW90no7FcxzR6ohHUYEKdxyfTBuAVjAuoil5miwoY8+6HNoSPbztyhMVvtCsQDtvQfyW1GNa7qvlQSqYxQW7b6nAR2W0OxNi4NgrFEqbMFrD+4CwwAg4PUWpvcQxYA==" />
    </form>
    

    @Html.AntiForgeryToken的使用:

    //Razor:
    <form id="form" action="withdraw/trans" method="post">
       @Html.AntiForgeryToken()
        <input name="account" type="text"/>
        <input name="amount" type="text"/>
        <input name="forAccount" type="text"/>
    </form>
    
    //Controller:添加特性[ValidateAntiForgeryToken]且必须是HttpPost
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActinResult Trans(string account,double amount,string forAccount)
    {
        return View();
    }
    

    get请求最好是只读的,对于有操作的请求最好用post来实现。


    参考:

  • 相关阅读:
    动态规划之 0-1背包问题及改进
    动态规划之矩阵连乘
    python3 入门 (四) 类与继承
    动态规划之最长公共子序列(LCS)
    java并发包分析之———AQS框架
    java并发包分析之———BlockingQueue
    java并发包分析之———Deque和LinkedBlockingDeque
    java并发包分析之———concurrentHashMap
    java并发包分析之———ConcurrentSkipListMap
    java并发包分析之———Atomic类型
  • 原文地址:https://www.cnblogs.com/JoeSnail/p/7743832.html
Copyright © 2020-2023  润新知