web攻击手段(二)CRSF

来源:互联网 发布:分簇算法的应用 编辑:程序博客网 时间:2024/06/01 08:38

  CRSF是跨站请求伪造:Cross site request forgery,是一种对网站的恶意利用。它和XSS跨站脚本攻击的不同是,XSS利用站点内的信任用户;CRSF则是通过伪装来自信任用户的请求,来利用受信任的网站。举例就是:攻击者盗用了你的身份,以你的名义向第三方信任网站发送恶意请求,如发邮件,发短信,转账交易等。


CSRF攻击原理


  下图简单阐述了CSRF攻击的思想:



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

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

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

  或许有些人认为:“如果我不满足以上两个条件中的一个,我就不会受到CSRF的攻击”。是的,确实如此,但你不能保证以下情况不会发生:

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

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

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


二、CSRF的防范


  CSRF的防御可以从服务端和客户端两方面着手,防御效果是从服务端着手效果比较好,现在一般的CSRF防御也都在服务端进行。


  1、验证HTTP Referer字段

  根据HTTP协议,在HTTP头中有一个字段叫Referer,它记录了该HTTP请求的来源地址。在通常情况下,访问一个安全受限页面的请求必须来自于同一个网站。可以在Filter中验证Referer,思路就是先取得 Referer 值,然后进行判断,当其非空并以 bank.example 开头时,则继续请求,否则的话可能是 CSRF 攻击,转到error.jsp 页面。

  

<pre name="code" class="java">// 从 HTTP 头中取得 Referer 值 String referer=request.getHeader("Referer"); // 判断 Referer 是否以 bank.example 开头 if((referer!=null) &&(referer.trim().startsWith(“bank.example”))){    chain.doFilter(request, response); }else{request.getRequestDispatcher(“error.jsp”).forward(request,response); } 

  2、在请求地址中添加token并验证

  抵御CSRF攻击的关键在于:在请求中放入攻击者所不能伪造的信息,并且该信息不存在于Cookie之中。鉴于此,系统开发者可以在HTTP请求中以参数的形式加入一个随机产生的token,并在服务器端建立一个拦截器来验证这个token,如果请求中没有token或者token内容不正确,则认为可能是CSRF攻击而拒绝该请求。

HttpServletRequest req = (HttpServletRequest)request; HttpSession s = req.getSession(); // 从 session 中得到 csrftoken 属性 String sToken = (String)s.getAttribute(“csrftoken”); if(sToken == null){    // 产生新的 token 放入 session 中    sToken = generateToken();    s.setAttribute(“csrftoken”,sToken);    chain.doFilter(request, response); } else{    // 从 HTTP 头中取得 csrftoken    String xhrToken = req.getHeader(“csrftoken”);    // 从请求参数中取得 csrftoken    String pToken = req.getParameter(“csrftoken”);    if(sToken != null && xhrToken != null && sToken.equals(xhrToken)){        chain.doFilter(request, response);    }else if(sToken != null && pToken != null && sToken.equals(pToken)){        chain.doFilter(request, response);    }else{request.getRequestDispatcher(“error.jsp”).forward(request,response);    } } 


0 0
原创粉丝点击