web攻击手段(二)CRSF

  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);
    }
 } 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值