zoukankan      html  css  js  c++  java
  • CSRF跨站请求伪造

    一、基本概念&原理

    CSRF: 跨站请求伪造(XSRF), 攻击者通过一些技术手段欺骗用户的浏览器去访问一个,自己曾经认证过的网站并运行一些操作(例如:以用户名义发送邮件、发送消息、甚至财产操作转账和购买商品等)。由于浏览器曾经对这个网站认证过,所以被访问的网站会认为是用户自己在操作而去运行。简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的

    举个栗子:用户user访问银行网站A,需要进行转账操作,现有一个恶意攻击网站B制作了一段js代码注入银行网站A中。js代码可以看作是拿着用户的身份证,冒充用户,进行恶意操作。

     正常情况下:用户user第一次登陆时,银行网站A会通过响应对象将cookie设置在浏览器中,在后续用户user访问网站时,浏览器会自动携带这个cookie给服务器,服务器再通过请求对象读取cookie值。

     CSRF攻击的情况下:假设用户user现已成功登陆银行网站A,所以用户浏览器上已经被银行网站A设置了cookie,若此时用户user不小心误入了恶意网站B所注入的js表单代码,那么这段js表单代码会携带着用户user的cookie给银行网站A发送请求,因为银行网站A是依据cookie来区分用户的,所以银行网站A并不知晓现在访问它的究竟是不是用户本身,它只判断请求中是否携带cookie。如果当前请求中携带了属于用户user的cookie,那么银行网站A就会认为现在访问它的就是用户user自己,所以恶意网站B可以随意的在它注入的js代码中大作文章,或许带着用户user的cookie冒充身份进行转账操作,用户user就这样在不知情的境况下造成财产损失。

    完成一次CSRF攻击,受害者需要具备的两个条件:

    • 登录受信任的网站A,并在本地生成Cookie。
    • 在不登出网站A的情况下,访问危险网站B。

    二、CSRF特性

    CSRF是一种依赖web浏览器的、cookie的网站攻击(deputy attack)具有以下特性:
    • 依靠用户标识(cookie)危害网站
    • 利用网站对用户标识的信任
    • 欺骗用户的浏览器发送HTTP请求给目标站点
    • 可以通过IMG标签会触发一个GET请求,可以利用它来实现CSRF攻击
     
     
    三、CSRF攻击的对象
     
      CSRF 攻击是黑客借助受害者的 cookie 骗取服务器的信任,但是黑客并不能直接拿到 cookie,也提取不到 cookie 的内容。另外,对于服务器返回的结果,因为浏览器遵循同源策略的限制,黑客也无法进行解析。因此,黑客无法获取用户信息,也无法从返回的结果中得到任何数据,他所能做的就是给服务器发送请求,以执行恶意请求中所描述的命令,在服务器端直接改变数据的值,而非窃取服务器中的数据。所以,我们要保护的对象是那些可以直接产生数据改变的服务,而对于读取数据的服务,则不需要进行 CSRF 的保护。比如银行系统中转账的请求会直接改变账户的金额,会遭到 CSRF 攻击,需要保护。而查询余额是对金额的读取操作,不会改变数据,CSRF 攻击无法解析服务器返回的结果,无需保护。
     
     

    四、防范措施

    防御 CSRF 攻击主要有三种策略:验证 HTTP Referer 字段;在请求地址中添加 token 并验证;在 HTTP 头中自定义属性并验证。

     1.验证 HTTP Referer 字段

        根据 HTTP 协议,在 HTTP 请求头中有一个字段叫 Referer,它记录了当前 HTTP 请求的来源地址。通常情况下,用户访问一个具有用户权限的页面(例如:用户必须登陆之后才能访问,或其他各种身份权限等)安全受限页面的请求来自于同一个网站,比如需要访问 转账页面,用户必须先登陆网站,然后点击页面上的按钮来触发转账事件。此时,这个转帐请求的 Referer 值就会是转账按钮所在的页面的 URL(假设以 bank.example 开头)。如果黑客要对银行网站实施 CSRF 攻击,他只能在他自己的网站构造请求,当用户误入了黑客的网站发送请求到银行时,该请求的 Referer 是指向黑客自己的网站 URL。因此,要防御 CSRF 攻击,银行网站只需要对于每一个转账请求,都验证它的 Referer 值就可,如果是以 bank.example 开头的域名,则说明该请求是来自银行网站自己的请求,是合法的。但如果 Referer 执行的是其他网站的话,则有可能是黑客的 CSRF 攻击,拒绝该请求。

      好处:方法简单易行,网站的普通开发人员不需要操心 CSRF 的漏洞,只需要在最后给所有安全敏感的请求,统一增加一个拦截器来检查 Referer 的值就可以。特别是对于当前现有的系统,不需要改变当前系统的任何已有代码和逻辑,没有风险,非常便捷。

      缺陷:a. 由于 Referer 的值是浏览器提供的,虽然 HTTP 协议上有明确的要求,但是每个浏览器对于 Referer 的具体实现可能有差别,我们并不能保证浏览器自身没有安全漏洞。使用验证 Referer 值的方法,就是把安全性全部都依赖于第三方(即浏览器)来保障。事实上,对于比如 IE6 浏览器已经有方法可以篡改Referer。如果银行网站A支持 IE6 浏览器,黑客完全可以把用户浏览器的 Referer 值设为以 bank.example 域名开头的地址,这样就可以通过验证,从而进行 CSRF 攻击。

         b. 因为 Referer 值会记录下用户的访问来源,但是用户自己是可以设置浏览器,使其在发送请求时不再提供 Referer。此时当他们正常访问银行网站时,网站会因为请求中没有 Referer 值而认为是 CSRF 攻击,拒绝合法用户的访问。

     

     2. 在请求头中添加自定义属性字段并验证

        CSRF 攻击之所以能够成功,是因为黑客可以完全伪造用户的请求,该请求中所有的用户验证信息都是存在于 cookie 中,因此黑客可以在不知道这些验证信息的情况下,直接利用用户自己的 cookie 来通过安全验证。由于浏览器遵循同源策略,黑客无法解析cookie获取用户信息,也无法从服务器返回的结果中得到任何数据,那么要抵御 CSRF的话,在请求头中放入一个黑客所不能伪造的信息(服务器自定义的一个特殊加密的信息标记),并且该信息不存在于 cookie 之中。可以在 HTTP 请求头中加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求头中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。通常用于 Ajax 方法中对于页面局部的异步刷新。

     

     3. 在请求的表单数据中添加隐藏字段并验证

        后端生成一个加密token,将其设置在cookie当中,专用于表单数据提交时的验证,并且前端在表单中多增加一个隐藏字段,每当用户提交表单数据时(post请求),将这个隐藏字段一并提交,后端再对表单中的token和cookie中的token进行对比验证。因为黑客是无法提取cookie当中的信息,自然他也无法得知表单中存在一个隐藏的token。如果是网站自己的请求当中,会带有这个隐藏字段,但黑客因为无法知晓表单中还有额外字段,所以黑客所发起的请求中没有此字段。我们可以据此区分:如果所提交的表单数据中不存在这个隐藏字段,或者跟后端生成的token结果不一致,则可认为是遭到了 CSRF 攻击而拒绝该请求。

  • 相关阅读:
    java 之 File类
    java 之 内部类
    java 之 泛型
    如何生成随机码
    sql中getdate()&convert的使用
    sql中Distinct&Count的用法
    C#中如何使用正则表达式
    Sql按照字段分组,选取其他字段最值所在的行记录
    为什么在属性中设置private set
    基本Sql语句汇总
  • 原文地址:https://www.cnblogs.com/hsmwlyl/p/10618546.html
Copyright © 2011-2022 走看看