自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

安全 應用安全
隨著Web2.0、社交網(wǎng)絡、微博等等一系列新型的互聯(lián)網(wǎng)產(chǎn)品的誕生,基于Web環(huán)境的互聯(lián)網(wǎng)應用越來越廣泛,企業(yè)信息化的過程中各種應用都架設在Web平臺上,Web業(yè)務的迅速發(fā)展也引起黑客們的強烈關注,接踵而至的就是Web安全威脅的凸顯。

隨著Web2.0、社交網(wǎng)絡、微博等等一系列新型的互聯(lián)網(wǎng)產(chǎn)品的誕生,基于Web環(huán)境的互聯(lián)網(wǎng)應用越來越廣泛,企業(yè)信息化的過程中各種應用都架設在Web平臺上,Web業(yè)務的迅速發(fā)展也引起黑客們的強烈關注,接踵而至的就是Web安全威脅的凸顯。

黑客利用網(wǎng)站操作系統(tǒng)的漏洞和Web服務程序的SQL注入漏洞等得到Web服務器的控制權限,輕則篡改網(wǎng)頁內容,重則竊取重要內部數(shù)據(jù),更為嚴重的則是在網(wǎng)頁中植入惡意代碼,使得網(wǎng)站訪問者受到侵害。

如今,Web安全成為焦點,但網(wǎng)站的漏洞還是頻頻出現(xiàn),在白帽子們進行網(wǎng)站測試時,恐怕對于SQL注入、XSS跨站、CSRF接觸最多,但對于網(wǎng)站的開發(fā)者們來說,對這些熟知多少?本文從開發(fā)者的角度,對于XSS和CSRF進行簡要概述。

PART1 XSS跨站腳本(Cross-site scripting)

XSS成因概括 :

XSS其實就是Html的注入問題,攻擊者的輸入沒有經(jīng)過嚴格的控制進入了數(shù)據(jù)庫,最終顯示給來訪的用戶,導致可以在來訪用戶的瀏覽器里以瀏覽用戶的身份執(zhí)行Html代碼,數(shù)據(jù)流程如下:攻擊者的Html輸入—>web程序—>進入數(shù)據(jù)庫—>web程序—>用戶瀏覽器。

檢測方法:

//通常有一些方式可以測試網(wǎng)站是否有正確處理特殊字符:

  1. ><script>alert(document.cookie)</script> 
  2. ='><script>alert(document.cookie)</script> 
  3. "><script>alert(document.cookie)</script> 
  4. <script>alert(document.cookie)</script> 
  5. <script>alert(vulnerable)</script> 
  6. %3Cscript%3Ealert('XSS')%3C/script%3E  
  7. <script>alert('XSS')</script> 
  8. <img src="javascript:alert('XSS')"> 
  9. <img src="http://xxx.com/yyy.png" onerror="alert('XSS')"> 
  10. <div style="height:expression(alert('XSS'),1)" />(這個僅限 IE 有效) 

攻擊手段和目的:

攻擊者使被攻擊者在瀏覽器中執(zhí)行腳本后,如果需要收集來自被攻擊者的數(shù)據(jù)(如cookie或其他敏感信息),可以自行架設一個網(wǎng)站,讓被攻擊者通過JavaScript等方式把收集好的數(shù)據(jù)作為參數(shù)提交,隨后以數(shù)據(jù)庫等形式記錄在攻擊者自己的服務器上。

a. 盜用 cookie ,獲取敏感信息。

b.利用植入 Flash ,通過 crossdomain 權限設置進一步獲取更高權限;或者利用Java等得到類似的操作。

c.利用 iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻擊)用戶的身份執(zhí)行一些管理動作,或執(zhí)行一些一般的如發(fā)微博、加好友、發(fā)私信等操作。

d.利用可被攻擊的域受到其他域信任的特點,以受信任來源的身份請求一些平時不允許的操作,如進行不當?shù)耐镀被顒印?/p>

e.在訪問量極大的一些頁面上的XSS可以攻擊一些小型網(wǎng)站,實現(xiàn)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腳本(順便指定了內容編碼),而非可以引發(fā)攻擊的HTML。

PART2 CSRF:冒充用戶之手

示意圖:

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

XSS 是實現(xiàn) CSRF 的諸多途徑中的一條,但絕對不是唯一的一條。一般習慣上把通過 XSS 來實現(xiàn)的 CSRF 稱為 XSRF。

CSRF 顧名思義,是偽造請求,冒充用戶在站內的正常操作。我們知道,絕大多數(shù)網(wǎng)站是通過 cookie 等方式辨識用戶身份(包括使用服務器端 Session 的網(wǎng)站,因為 Session ID 也是大多保存在 cookie 里面的),再予以授權的。所以要偽造用戶的正常操作,最好的方法是通過 XSS 或鏈接欺騙等途徑,讓用戶在本機(即擁有身份 cookie 的瀏覽器端)發(fā)起用戶所不知道的請求。

要完成一次CSRF攻擊,受害者必須依次完成兩個步驟:

1.登錄受信任網(wǎng)站A,并在本地生成Cookie。

2.在不登出A的情況下,訪問危險網(wǎng)站B。

看到這里,你也許會說:“如果我不滿足以上兩個條件中的一個,我就不會受到CSRF的攻擊”。是的,確實如此,但你不能保證以下情況不會發(fā)生:

1.你不能保證你登錄了一個網(wǎng)站后,不再打開一個tab頁面并訪問另外的網(wǎng)站。

2.你不能保證你關閉瀏覽器了后,你本地的Cookie立刻過期,你上次的會話已經(jīng)結束。(事實上,關閉瀏覽器不能結束一個會話,但大多數(shù)人都會錯誤的認為關閉瀏覽器就等于退出登錄/結束會話了……)

3.上圖中所謂的攻擊網(wǎng)站,可能是一個存在其他漏洞的可信任的經(jīng)常被人訪問的網(wǎng)站。

上面大概地講了一下CSRF攻擊的思想,下面我將用幾個例子詳細說說具體的CSRF攻擊,這里我以一個銀行轉賬的操作作為例子(僅僅是例子,真實的銀行網(wǎng)站沒這么傻:>)

示例1:

銀行網(wǎng)站A,它以GET請求來完成銀行轉賬的操作,如:

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

危險網(wǎng)站B,它里面有一段HTML的代碼如下:

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

首先,你登錄了銀行網(wǎng)站A,然后訪問危險網(wǎng)站B,噢,這時你會發(fā)現(xiàn)你的銀行賬戶少了1000塊……

為什么會這樣呢?原因是銀行網(wǎng)站A違反了HTTP規(guī)范,使用GET請求更新資源。在訪問危險網(wǎng)站B的之前,你已經(jīng)登錄了銀行網(wǎng)站A,而B中的img以GET的方式請求第三方資源(這里的第三方就是指銀行網(wǎng)站了,原本這是一個合法的請求,但這里被不法分子利用了),所以你的瀏覽器會帶上你的銀行網(wǎng)站A的Cookie發(fā)出Get請求,去獲取資源“http://www.mybank.com/Transfer.php?toBankId=11&money=1000”,結果銀行網(wǎng)站服務器收到請求后,認為這是一個更新資源操作(轉賬操作),所以就立刻進行轉賬操作……

 

示例2:

為了杜絕上面的問題,銀行決定改用POST請求完成轉賬操作。

銀行網(wǎng)站A的WEB表單如下:

  1. <form action="Transfer.php" method="POST"> 
  2.         <p>ToBankId: <input type="text" name="toBankId" /></p> 
  3.         <p>Money: <input type="text" name="money" /></p> 
  4.         <p><input type="submit" value="Transfer" /></p> 
  5. </form> 

后臺處理頁面Transfer.php如下:

  1. <?php  
  2.       session_start();  
  3.     if (isset($_REQUEST[&#039;toBankId&#039;] && isset($_REQUEST[&#039;money&#039;]))  
  4.     {  
  5.        buy_stocks($_REQUEST[&#039;toBankId&#039;], $_REQUEST[&#039;money&#039;]);  
  6.     }  

危險網(wǎng)站B,仍然只是包含那句HTML代碼:

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

和示例1中的操作一樣,你首先登錄了銀行網(wǎng)站A,然后訪問危險網(wǎng)站B,結果…..和示例1一樣,你再次沒了1000塊~T_T,這次事故的原因是:銀行后臺使用了$_REQUEST去獲取請求的數(shù)據(jù),而$_REQUEST既可以獲取GET請求的數(shù)據(jù),也可以獲取POST請求的數(shù)據(jù),這就造成了在后臺處理程序無法區(qū)分這到底是GET請求的數(shù)據(jù)還是POST請求的數(shù)據(jù)。在PHP中,可以使用$_GET和$_POST分別獲取GET請求和POST請求的數(shù)據(jù)。在JAVA中,用于獲取請求數(shù)據(jù)request一樣存在不能區(qū)分GET請求數(shù)據(jù)和POST數(shù)據(jù)的問題。

示例3:

經(jīng)過前面2個慘痛的教訓,銀行決定把獲取請求數(shù)據(jù)的方法也改了,改用$_POST,只獲取POST請求的數(shù)據(jù),后臺處理頁面Transfer.php代碼如下:

  1. <?php  
  2.      session_start();  
  3.      if (isset($_POST['toBankId'] && isset($_POST['money']))  
  4.      {  
  5.         buy_stocks($_POST['toBankId'], $_POST['money']);  
  6.      }  
  7. ?> 

然而,危險網(wǎng)站B與時俱進,它改了一下代碼:

  1. <html> 
  2.       <head> 
  3.         <script type="text/javascript"> 
  4.           function steal()  
  5.           {  
  6.                    iframe = document.frames["steal"];  
  7.                    iframe.document.Submit("transfer");  
  8.           }  
  9.         </script> 
  10.       </head> 
  11.       <body onload="steal()"> 
  12.         <iframe name="steal" display="none"> 
  13.           <form method="POST" name="transfer" action="http://www.myBank.com/Transfer.php"> 
  14.             <input type="hidden" name="toBankId" value="11"> 
  15.             <input type="hidden" name="money" value="1000"> 
  16.           </form> 
  17.         </iframe> 
  18.       </body> 
  19. </html> 

如果用戶仍是繼續(xù)上面的操作,很不幸,結果將會是再次不見1000塊……因為這里危險網(wǎng)站B暗地里發(fā)送了POST請求到銀行!

總結一下上面3個例子,CSRF主要的攻擊模式基本上是以上的3種,其中以第1,2種最為嚴重,因為觸發(fā)條件很簡單,一個img就可以了,而第3種比較麻煩,需要使用JavaScript,所以使用的機會會比前面的少很多,但無論是哪種情況,只要觸發(fā)了CSRF攻擊,后果都有可能很嚴重。

 

理解上面的3種攻擊模式,其實可以看出,CSRF攻擊是源于WEB的隱式身份驗證機制!WEB的身份驗證機制雖然可以保證一個請求是來自于某個用戶的瀏覽器,但卻無法保證該請求是用戶批準發(fā)送的!

如何防御?

請求令牌(一種簡單有效的防御方法):

首先服務器端要以某種策略生成隨機字符串,作為令牌(token),保存在 Session 里。然后在發(fā)出請求的頁面,把該令牌以隱藏域一類的形式,與其他信息一并發(fā)出。在接收請求的頁面,把接收到的信息中的令牌與 Session 中的令牌比較,只有一致的時候才處理請求,處理完成后清理session中的值,否則返回 HTTP 403 拒絕請求或者要求用戶重新登陸驗證身份

令牌來防止 CSRF 有以下幾點要注意:

a.雖然請求令牌原理和驗證碼有相似之處,但不應該像驗證碼一樣,全局使用一個 Session Key。因為請求令牌的方法在理論上是可破解的,破解方式是解析來源頁面的文本,獲取令牌內容。如果全局使用一個 Session Key,那么危險系數(shù)會上升。原則上來說,每個頁面的請求令牌都應該放在獨立的 Session Key 中。我們在設計服務器端的時候,可以稍加封裝,編寫一個令牌工具包,將頁面的標識作為 Session 中保存令牌的鍵。

b.在 ajax 技術應用較多的場合,因為很有請求是 JavaScript 發(fā)起的,使用靜態(tài)的模版輸出令牌值或多或少有些不方便。但無論如何,請不要提供直接獲取令牌值的 API。這么做無疑是鎖上了大門,卻又把鑰匙放在門口,讓我們的請求令牌退化為同步令牌。

c.第一點說了請求令牌理論上是可破解的,所以非常重要的場合,應該考慮使用驗證碼(令牌的一種升級,目前來看破解難度極大),或者要求用戶再次輸入密碼(亞馬遜、淘寶的做法)。但這兩種方式用戶體驗都不好,所以需要產(chǎn)品開發(fā)者權衡。

d.無論是普通的請求令牌還是驗證碼,服務器端驗證過一定記得銷毀。忘記銷毀用過的令牌是個很低級但是殺傷力很大的錯誤。我們學校的選課系統(tǒng)就有這個問題,驗證碼用完并未銷毀,故只要獲取一次驗證碼圖片,其中的驗證碼可以在多次請求中使用(只要不再次刷新驗證碼圖片),一直用到。

如下也列出一些據(jù)說能有效防范 CSRF,其實效果甚微或甚至無效的做法:

a.通過 referer 判定來源頁面:referer 是在 HTTP Request Head 里面的,也就是由請求的發(fā)送者決定的。如果我喜歡,可以給 referer 任何值。當然這個做法并不是毫無作用,起碼可以防小白。但我覺得性價比不如令牌。

b.過濾所有用戶發(fā)布的鏈接:這個是最無效的做法,因為首先攻擊者不一定要從站內發(fā)起請求(上面提到過了),而且就算從站內發(fā)起請求,途徑也遠遠不知鏈接一條。比如

 <img src="./create_post.php" /> 

就是個不錯的選擇,還不需要用戶去點擊,只要用戶的瀏覽器會自動加載圖片,就會自動發(fā)起請求。

 

c.在請求發(fā)起頁面用 alert 彈窗提醒用戶:這個方法看上去能干擾站外通過 iframe 發(fā)起的 CSRF,但攻擊者也可以考慮用 window.alert = function(){}; 把 alert 弄啞,或者干脆脫離 iframe,使用 Flash 來達到目的。

總體來說,目前防御 CSRF 的諸多方法還沒幾個能徹底無解的。 作為開發(fā)者,我們能做的就是盡量提高破解難度。當破解難度達到一定程度,網(wǎng)站就逼近于絕對安全的位置了

參考文獻

[1].Preventing CSRF

[2].Security Corner: Cross-Site Request Forgeries

[3].《Web安全測試之跨站請求偽造(CSRF)》

[4].百度百科-CSRF、XSS

責任編輯:藍雨淚 來源: FreeBuf
相關推薦

2019-02-25 09:20:53

2022-02-08 12:06:12

云計算

2020-10-19 08:53:08

Redis性能指標監(jiān)控

2011-08-25 12:51:02

2018-02-02 10:56:19

屏蔽機房擴建

2023-06-07 08:18:25

2020-03-25 08:47:22

智能邊緣邊緣計算網(wǎng)絡

2012-12-27 10:58:24

KVMKVM概念

2023-10-25 08:17:06

Lite模式代理類

2023-10-29 08:35:47

AndroidAOP編程

2021-06-06 18:22:04

PprofGopher邏輯

2022-06-07 07:37:40

線程進程開發(fā)

2011-08-23 11:03:35

ATM

2023-09-07 10:26:50

接口測試自動化測試

2019-08-07 17:18:18

云計算云原生函數(shù)

2025-01-16 10:41:40

2018-01-06 10:38:51

Ping抓包 ICMP協(xié)議

2023-08-17 10:12:04

前端整潔架構

2015-11-09 10:44:37

DevOpsIT運維

2020-12-10 09:00:00

開發(fā).NET工具
點贊
收藏

51CTO技術棧公眾號