压在透明的玻璃上c-国产精品国产一级A片精品免费-国产精品视频网-成人黄网站18秘 免费看|www.tcsft.com

科普:對于XSS和CSRF你究竟了解多少

  隨著Web2.0、社交網絡、微博等等一系列新型的互聯網產品的誕生,基于Web環境的互聯網應用越來越廣泛,企業信息化的過程中各種應用都架設在Web平臺上,Web業務的迅速發展也引起黑客們的強烈關注,接踵而至的就是Web安全威脅的凸顯。
 
  黑客利用網站操作系統的漏洞和Web服務程序的SQL注入漏洞等得到Web服務器的控制權限,輕則篡改網頁內容,重則竊取重要內部數據,更為嚴重的則是在網頁中植入惡意代碼,使得網站訪問者受到侵害。
 
  如今,Web安全成為焦點,但網站的漏洞還是頻頻出現,在白帽子們進行網站測試時,恐怕對于SQL注入、XSS跨站、CSRF接觸最多,但對于網站的開發者們來說,對這些熟知多少?本文從開發者的角度,對于XSS和CSRF進行簡要概述。
 
  PART1 XSS跨站腳本(Cross-site scripting)
 
  XSS成因概括 :
 
  XSS其實就是Html的注入問題,攻擊者的輸入沒有經過嚴格的控制進入了數據庫,最終顯示給來訪的用戶,導致可以在來訪用戶的瀏覽器里以瀏覽用戶的身份執行Html代碼,數據流程如下:攻擊者的Html輸入—>web程序—>進入數據庫—>web程序—>用戶瀏覽器。
 
  檢測方法:
 
  //通常有一些方式可以測試網站是否有正確處理特殊字符:
 
  >='>"><script>alert(document.cookie)</script> <script>alert(document.cookie)</script> <script>alert(vulnerable)</script> %3Cscript%3Ealert('XSS')%3C/script%3E  <script>alert('XSS')</script>
 
  (這個僅限 IE 有效) 攻擊手段和目的:
 
  攻擊者使被攻擊者在瀏覽器中執行腳本后,如果需要收集來自被攻擊者的數據(如cookie或其他敏感信息),可以自行架設一個網站,讓被攻擊者通過JavaScript等方式把收集好的數據作為參數提交,隨后以數據庫等形式記錄在攻擊者自己的服務器上。
 
  a. 盜用 cookie ,獲取敏感信息。
 
  b.利用植入 Flash ,通過 crossdomain 權限設置進一步獲取更高權限;或者利用Java等得到類似的操作。
 
  c.利用 iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻擊)用戶的身份執行一些管理動作,或執行一些一般的如發微博、加好友、發私信等操作。
 
  d.利用可被攻擊的域受到其他域信任的特點,以受信任來源的身份請求一些平時不允許的操作,如進行不當的投票活動。
 
  e.在訪問量極大的一些頁面上的XSS可以攻擊一些小型網站,實現DDoS攻擊的效果。
 
  漏洞的防御和利用:
 
  避免XSS的方法之一主要是將用戶所提供的內容進行過濾,許多語言都有提供對HTML的過濾:
 
  PHP的htmlentities()或是htmlspecialchars()。
 
  Python的cgi.escape()。
 
  ASP的Server.HTMLEncode()。
 
  ASP.NET的Server.HtmlEncode()或功能更強的Microsoft Anti-Cross Site Scripting Library
 
  Java的xssprotect(Open Source Library)。
 
  Node.js的node-validator。使用HTTP頭指定類型:
 
  很多時候可以使用HTTP頭指定內容的類型,使得輸出的內容避免被作為HTML解析。如在PHP語言中使用以下代碼:
 
  header
 
  ('Content-Type: text/javascript; charset=utf-8');即可強行指定輸出內容為文本/JavaScript腳本(順便指定了內容編碼),而非可以引發攻擊的HTML。
 
  PART2 CSRF:冒充用戶之手
 
  XSS 是實現 CSRF 的諸多途徑中的一條,但絕對不是唯一的一條。一般習慣上把通過 XSS 來實現的 CSRF 稱為 XSRF。
 
  CSRF 顧名思義,是偽造請求,冒充用戶在站內的正常操作。我們知道,絕大多數網站是通過 cookie 等方式辨識用戶身份(包括使用服務器端 Session 的網站,因為 Session ID 也是大多保存在 cookie 里面的),再予以授權的。所以要偽造用戶的正常操作,最好的方法是通過 XSS 或鏈接欺騙等途徑,讓用戶在本機(即擁有身份 cookie 的瀏覽器端)發起用戶所不知道的請求。
 
  要完成一次CSRF攻擊,受害者必須依次完成兩個步驟:
 
  1.登錄受信任網站A,并在本地生成Cookie。
 
  2.在不登出A的情況下,訪問危險網站B。
 
  看到這里,你也許會說:“如果我不滿足以上兩個條件中的一個,我就不會受到CSRF的攻擊”。是的,確實如此,但你不能保證以下情況不會發生:
 
  1.你不能保證你登錄了一個網站后,不再打開一個tab頁面并訪問另外的網站。
 
  2.你不能保證你關閉瀏覽器了后,你本地的Cookie立刻過期,你上次的會話已經結束。(事實上,關閉瀏覽器不能結束一個會話,但大多數人都會錯誤的認為關閉瀏覽器就等于退出登錄/結束會話了……)
 
  3.上圖中所謂的攻擊網站,可能是一個存在其他漏洞的可信任的經常被人訪問的網站。
 
  上面大概地講了一下CSRF攻擊的思想,下面我將用幾個例子詳細說說具體的CSRF攻擊,這里我以一個銀行轉賬的操作作為例子(僅僅是例子,真實的銀行網站沒這么傻:>)
 
  示例1:
 
  銀行網站A,它以GET請求來完成銀行轉賬的操作,如:
 
  http://www.mybank.com/Transfer.php?toBankId=11&money=1000危險網站B,它里面有一段HTML的代碼如下:
 
   首先,你登錄了銀行網站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表單如下:
 
  ToBankId: 
 
    Money: 
 
    后臺處理頁面Transfer.php如下:
 
  <?php      session_start();      if (isset($_REQUEST[';toBankId';] && isset($_REQUEST[';money';]))      {       buy_stocks($_REQUEST[';toBankId';], $_REQUEST[';money';]);      }  > 危險網站B,仍然只是包含那句HTML代碼:
 
   和示例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與時俱進,它改了一下代碼:
 
  IFrame    如果用戶仍是繼續上面的操作,很不幸,結果將會是再次不見1000塊……因為這里危險網站B暗地里發送了POST請求到銀行!
 
  總結一下上面3個例子,CSRF主要的攻擊模式基本上是以上的3種,其中以第1,2種最為嚴重,因為觸發條件很簡單,一個img就可以了,而第3種比較麻煩,需要使用JavaScript,所以使用的機會會比前面的少很多,但無論是哪種情況,只要觸發了CSRF攻擊,后果都有可能很嚴重。
 
  理解上面的3種攻擊模式,其實可以看出,CSRF攻擊是源于WEB的隱式身份驗證機制!WEB的身份驗證機制雖然可以保證一個請求是來自于某個用戶的瀏覽器,但卻無法保證該請求是用戶批準發送的!
 
  如何防御?
 
  請求令牌(一種簡單有效的防御方法):
 
  首先服務器端要以某種策略生成隨機字符串,作為令牌(token),保存在 Session 里。然后在發出請求的頁面,把該令牌以隱藏域一類的形式,與其他信息一并發出。在接收請求的頁面,把接收到的信息中的令牌與 Session 中的令牌比較,只有一致的時候才處理請求,處理完成后清理session中的值,否則返回 HTTP 403 拒絕請求或者要求用戶重新登陸驗證身份
 
  令牌來防止 CSRF 有以下幾點要注意:
 
  a.雖然請求令牌原理和驗證碼有相似之處,但不應該像驗證碼一樣,全局使用一個 Session Key。因為請求令牌的方法在理論上是可破解的,破解方式是解析來源頁面的文本,獲取令牌內容。如果全局使用一個 Session Key,那么危險系數會上升。原則上來說,每個頁面的請求令牌都應該放在獨立的 Session Key 中。我們在設計服務器端的時候,可以稍加封裝,編寫一個令牌工具包,將頁面的標識作為 Session 中保存令牌的鍵。
 
  b.在 ajax 技術應用較多的場合,因為很有請求是 JavaScript 發起的,使用靜態的模版輸出令牌值或多或少有些不方便。但無論如何,請不要提供直接獲取令牌值的 API。這么做無疑是鎖上了大門,卻又把鑰匙放在門口,讓我們的請求令牌退化為同步令牌。
 
  c.第一點說了請求令牌理論上是可破解的,所以非常重要的場合,應該考慮使用驗證碼(令牌的一種升級,目前來看破解難度極大),或者要求用戶再次輸入密碼(亞馬遜、淘寶的做法)。但這兩種方式用戶體驗都不好,所以需要產品開發者權衡。
 
  d.無論是普通的請求令牌還是驗證碼,服務器端驗證過一定記得銷毀。忘記銷毀用過的令牌是個很低級但是殺傷力很大的錯誤。我們學校的選課系統就有這個問題,驗證碼用完并未銷毀,故只要獲取一次驗證碼圖片,其中的驗證碼可以在多次請求中使用(只要不再次刷新驗證碼圖片),一直用到。
 
  如下也列出一些據說能有效防范 CSRF,其實效果甚微或甚至無效的做法:
 
  a.通過 referer 判定來源頁面:referer 是在 HTTP Request Head 里面的,也就是由請求的發送者決定的。如果我喜歡,可以給 referer 任何值。當然這個做法并不是毫無作用,起碼可以防小白。但我覺得性價比不如令牌。
 
  b.過濾所有用戶發布的鏈接:這個是最無效的做法,因為首先攻擊者不一定要從站內發起請求(上面提到過了),而且就算從站內發起請求,途徑也遠遠不知鏈接一條。比如
 
   就是個不錯的選擇,還不需要用戶去點擊,只要用戶的瀏覽器會自動加載圖片,就會自動發起請求。
 
  c.在請求發起頁面用 alert 彈窗提醒用戶:這個方法看上去能干擾站外通過 iframe 發起的 CSRF,但攻擊者也可以考慮用 window.alert = function(){}; 把 alert 弄啞,或者干脆脫離 iframe,使用 Flash 來達到目的。
 
  總體來說,目前防御 CSRF 的諸多方法還沒幾個能徹底無解的。 作為開發者,我們能做的就是盡量提高破解難度。當破解難度達到一定程度,網站就逼近于絕對安全的位置了
 

上一篇:智能無懼挑戰 山石網科轟動RSA2015

下一篇:盤點Wi-Fi安全免費測試工具