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

創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、臨潼網(wǎng)絡(luò)推廣、微信小程序開發(fā)、臨潼網(wǎng)絡(luò)營(yíng)銷、臨潼企業(yè)策劃、臨潼品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供臨潼建站搭建服務(wù),24小時(shí)服務(wù)熱線:13518219792,官方網(wǎng)址:www.cdcxhl.com
黑客利用網(wǎng)站操作系統(tǒng)的漏洞和Web服務(wù)程序的SQL注入漏洞等得到Web服務(wù)器的控制權(quán)限,輕則篡改網(wǎng)頁(yè)內(nèi)容,重則竊取重要內(nèi)部數(shù)據(jù),更為嚴(yán)重的則是在網(wǎng)頁(yè)中植入惡意代碼,使得網(wǎng)站訪問者受到侵害。
如今,Web安全成為焦點(diǎn),但網(wǎng)站的漏洞還是頻頻出現(xiàn),在白帽子們進(jìn)行網(wǎng)站測(cè)試時(shí),恐怕對(duì)于SQL注入、XSS跨站、CSRF接觸最多,但對(duì)于網(wǎng)站的開發(fā)者們來說,對(duì)這些熟知多少?本文從開發(fā)者的角度,對(duì)于XSS和CSRF進(jìn)行簡(jiǎn)要概述。
PART1 XSS跨站腳本(Cross-site scripting)
XSS成因概括 :
XSS其實(shí)就是Html的注入問題,攻擊者的輸入沒有經(jīng)過嚴(yán)格的控制進(jìn)入了數(shù)據(jù)庫(kù),最終顯示給來訪的用戶,導(dǎo)致可以在來訪用戶的瀏覽器里以瀏覽用戶的身份執(zhí)行Html代碼,數(shù)據(jù)流程如下:攻擊者的Html輸入—>web程序—>進(jìn)入數(shù)據(jù)庫(kù)—>web程序—>用戶瀏覽器。
檢測(cè)方法:
//通常有一些方式可以測(cè)試網(wǎng)站是否有正確處理特殊字符:
- >
- ='>
- ">
- %3Cscript%3Ealert('XSS')%3C/script%3E
- (這個(gè)僅限 IE 有效)
攻擊手段和目的:
攻擊者使被攻擊者在瀏覽器中執(zhí)行腳本后,如果需要收集來自被攻擊者的數(shù)據(jù)(如cookie或其他敏感信息),可以自行架設(shè)一個(gè)網(wǎng)站,讓被攻擊者通過JavaScript等方式把收集好的數(shù)據(jù)作為參數(shù)提交,隨后以數(shù)據(jù)庫(kù)等形式記錄在攻擊者自己的服務(wù)器上。
a. 盜用 cookie ,獲取敏感信息。
b.利用植入 Flash ,通過 crossdomain 權(quán)限設(shè)置進(jìn)一步獲取更高權(quán)限;或者利用Java等得到類似的操作。
c.利用 iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻擊)用戶的身份執(zhí)行一些管理動(dòng)作,或執(zhí)行一些一般的如發(fā)微博、加好友、發(fā)私信等操作。
d.利用可被攻擊的域受到其他域信任的特點(diǎn),以受信任來源的身份請(qǐng)求一些平時(shí)不允許的操作,如進(jìn)行不當(dāng)?shù)耐镀被顒?dòng)。
e.在訪問量極大的一些頁(yè)面上的XSS可以攻擊一些小型網(wǎng)站,實(shí)現(xiàn)DDoS攻擊的效果。
漏洞的防御和利用:
避免XSS的方法之一主要是將用戶所提供的內(nèi)容進(jìn)行過濾,許多語(yǔ)言都有提供對(duì)HTML的過濾:
PHP的htmlentities()或是htmlspecialchars()。 Python的cgi.escape()。 ASP的Server.HTMLEncode()。 ASP.NET的Server.HtmlEncode()或功能更強(qiáng)的Microsoft Anti-Cross Site Scripting Library Java的xssprotect(Open Source Library)。 Node.js的node-validator。
使用HTTP頭指定類型:
很多時(shí)候可以使用HTTP頭指定內(nèi)容的類型,使得輸出的內(nèi)容避免被作為HTML解析。如在PHP語(yǔ)言中使用以下代碼:
header
('Content-Type: text/javascript; charset=utf-8');即可強(qiáng)行指定輸出內(nèi)容為文本/JavaScript腳本(順便指定了內(nèi)容編碼),而非可以引發(fā)攻擊的HTML。
PART2 CSRF:冒充用戶之手
示意圖:
XSS 是實(shí)現(xiàn) CSRF 的諸多途徑中的一條,但絕對(duì)不是唯一的一條。一般習(xí)慣上把通過 XSS 來實(shí)現(xiàn)的 CSRF 稱為 XSRF。
CSRF 顧名思義,是偽造請(qǐng)求,冒充用戶在站內(nèi)的正常操作。我們知道,絕大多數(shù)網(wǎng)站是通過 cookie 等方式辨識(shí)用戶身份(包括使用服務(wù)器端 Session 的網(wǎng)站,因?yàn)?Session ID 也是大多保存在 cookie 里面的),再予以授權(quán)的。所以要偽造用戶的正常操作,最好的方法是通過 XSS 或鏈接欺騙等途徑,讓用戶在本機(jī)(即擁有身份 cookie 的瀏覽器端)發(fā)起用戶所不知道的請(qǐng)求。
要完成一次CSRF攻擊,受害者必須依次完成兩個(gè)步驟:
1.登錄受信任網(wǎng)站A,并在本地生成Cookie。
2.在不登出A的情況下,訪問危險(xiǎn)網(wǎng)站B。
看到這里,你也許會(huì)說:“如果我不滿足以上兩個(gè)條件中的一個(gè),我就不會(huì)受到CSRF的攻擊”。是的,確實(shí)如此,但你不能保證以下情況不會(huì)發(fā)生:
1.你不能保證你登錄了一個(gè)網(wǎng)站后,不再打開一個(gè)tab頁(yè)面并訪問另外的網(wǎng)站。
2.你不能保證你關(guān)閉瀏覽器了后,你本地的Cookie立刻過期,你上次的會(huì)話已經(jīng)結(jié)束。(事實(shí)上,關(guān)閉瀏覽器不能結(jié)束一個(gè)會(huì)話,但大多數(shù)人都會(huì)錯(cuò)誤的認(rèn)為關(guān)閉瀏覽器就等于退出登錄/結(jié)束會(huì)話了……)
3.上圖中所謂的攻擊網(wǎng)站,可能是一個(gè)存在其他漏洞的可信任的經(jīng)常被人訪問的網(wǎng)站。
上面大概地講了一下CSRF攻擊的思想,下面我將用幾個(gè)例子詳細(xì)說說具體的CSRF攻擊,這里我以一個(gè)銀行轉(zhuǎn)賬的操作作為例子(僅僅是例子,真實(shí)的銀行網(wǎng)站沒這么傻:>)
示例1:
銀行網(wǎng)站A,它以GET請(qǐng)求來完成銀行轉(zhuǎn)賬的操作,如:
http://www.mybank.com/Transfer.php?toBankId=11&money=1000
危險(xiǎn)網(wǎng)站B,它里面有一段HTML的代碼如下:
首先,你登錄了銀行網(wǎng)站A,然后訪問危險(xiǎn)網(wǎng)站B,噢,這時(shí)你會(huì)發(fā)現(xiàn)你的銀行賬戶少了1000塊……
為什么會(huì)這樣呢?原因是銀行網(wǎng)站A違反了HTTP規(guī)范,使用GET請(qǐng)求更新資源。在訪問危險(xiǎn)網(wǎng)站B的之前,你已經(jīng)登錄了銀行網(wǎng)站A,而B中的img以GET的方式請(qǐng)求第三方資源(這里的第三方就是指銀行網(wǎng)站了,原本這是一個(gè)合法的請(qǐng)求,但這里被不法分子利用了),所以你的瀏覽器會(huì)帶上你的銀行網(wǎng)站A的Cookie發(fā)出Get請(qǐng)求,去獲取資源“http://www.mybank.com/Transfer.php?toBankId=11&money=1000”,結(jié)果銀行網(wǎng)站服務(wù)器收到請(qǐng)求后,認(rèn)為這是一個(gè)更新資源操作(轉(zhuǎn)賬操作),所以就立刻進(jìn)行轉(zhuǎn)賬操作……
示例2:
為了杜絕上面的問題,銀行決定改用POST請(qǐng)求完成轉(zhuǎn)賬操作。
銀行網(wǎng)站A的WEB表單如下:
ToBankId:
Money:
后臺(tái)處理頁(yè)面Transfer.php如下:
- session_start();
- if (isset($_REQUEST['toBankId'] && isset($_REQUEST['money']))
- {
- buy_stocks($_REQUEST['toBankId'], $_REQUEST['money']);
- }
- >
危險(xiǎn)網(wǎng)站B,仍然只是包含那句HTML代碼:
和示例1中的操作一樣,你首先登錄了銀行網(wǎng)站A,然后訪問危險(xiǎn)網(wǎng)站B,結(jié)果…..和示例1一樣,你再次沒了1000塊~T_T,這次事故的原因是:銀行后臺(tái)使用了$_REQUEST去獲取請(qǐng)求的數(shù)據(jù),而$_REQUEST既可以獲取GET請(qǐng)求的數(shù)據(jù),也可以獲取POST請(qǐng)求的數(shù)據(jù),這就造成了在后臺(tái)處理程序無(wú)法區(qū)分這到底是GET請(qǐng)求的數(shù)據(jù)還是POST請(qǐng)求的數(shù)據(jù)。在PHP中,可以使用$_GET和$_POST分別獲取GET請(qǐng)求和POST請(qǐng)求的數(shù)據(jù)。在JAVA中,用于獲取請(qǐng)求數(shù)據(jù)request一樣存在不能區(qū)分GET請(qǐng)求數(shù)據(jù)和POST數(shù)據(jù)的問題。
示例3:
經(jīng)過前面2個(gè)慘痛的教訓(xùn),銀行決定把獲取請(qǐng)求數(shù)據(jù)的方法也改了,改用$_POST,只獲取POST請(qǐng)求的數(shù)據(jù),后臺(tái)處理頁(yè)面Transfer.php代碼如下:
- session_start();
- if (isset($_POST['toBankId'] && isset($_POST['money']))
- {
- buy_stocks($_POST['toBankId'], $_POST['money']);
- }
- ?>
然而,危險(xiǎn)網(wǎng)站B與時(shí)俱進(jìn),它改了一下代碼:
- function steal()
- {
- iframe = document.frames["steal"];
- iframe.document.Submit("transfer");
- }
如果用戶仍是繼續(xù)上面的操作,很不幸,結(jié)果將會(huì)是再次不見1000塊……因?yàn)檫@里危險(xiǎn)網(wǎng)站B暗地里發(fā)送了POST請(qǐng)求到銀行!
總結(jié)一下上面3個(gè)例子,CSRF主要的攻擊模式基本上是以上的3種,其中以第1,2種最為嚴(yán)重,因?yàn)橛|發(fā)條件很簡(jiǎn)單,一個(gè)img就可以了,而第3種比較麻煩,需要使用JavaScript,所以使用的機(jī)會(huì)會(huì)比前面的少很多,但無(wú)論是哪種情況,只要觸發(fā)了CSRF攻擊,后果都有可能很嚴(yán)重。
理解上面的3種攻擊模式,其實(shí)可以看出,CSRF攻擊是源于WEB的隱式身份驗(yàn)證機(jī)制!WEB的身份驗(yàn)證機(jī)制雖然可以保證一個(gè)請(qǐng)求是來自于某個(gè)用戶的瀏覽器,但卻無(wú)法保證該請(qǐng)求是用戶批準(zhǔn)發(fā)送的!
如何防御?
請(qǐng)求令牌(一種簡(jiǎn)單有效的防御方法):
首先服務(wù)器端要以某種策略生成隨機(jī)字符串,作為令牌(token),保存在 Session 里。然后在發(fā)出請(qǐng)求的頁(yè)面,把該令牌以隱藏域一類的形式,與其他信息一并發(fā)出。在接收請(qǐng)求的頁(yè)面,把接收到的信息中的令牌與 Session 中的令牌比較,只有一致的時(shí)候才處理請(qǐng)求,處理完成后清理session中的值,否則返回 HTTP 403 拒絕請(qǐng)求或者要求用戶重新登陸驗(yàn)證身份
令牌來防止 CSRF 有以下幾點(diǎn)要注意:
a.雖然請(qǐng)求令牌原理和驗(yàn)證碼有相似之處,但不應(yīng)該像驗(yàn)證碼一樣,全局使用一個(gè) Session Key。因?yàn)檎?qǐng)求令牌的方法在理論上是可破解的,破解方式是解析來源頁(yè)面的文本,獲取令牌內(nèi)容。如果全局使用一個(gè) Session Key,那么危險(xiǎn)系數(shù)會(huì)上升。原則上來說,每個(gè)頁(yè)面的請(qǐng)求令牌都應(yīng)該放在獨(dú)立的 Session Key 中。我們?cè)谠O(shè)計(jì)服務(wù)器端的時(shí)候,可以稍加封裝,編寫一個(gè)令牌工具包,將頁(yè)面的標(biāo)識(shí)作為 Session 中保存令牌的鍵。
b.在 ajax 技術(shù)應(yīng)用較多的場(chǎng)合,因?yàn)楹苡姓?qǐng)求是 JavaScript 發(fā)起的,使用靜態(tài)的模版輸出令牌值或多或少有些不方便。但無(wú)論如何,請(qǐng)不要提供直接獲取令牌值的 API。這么做無(wú)疑是鎖上了大門,卻又把鑰匙放在門口,讓我們的請(qǐng)求令牌退化為同步令牌。
c.第一點(diǎn)說了請(qǐng)求令牌理論上是可破解的,所以非常重要的場(chǎng)合,應(yīng)該考慮使用驗(yàn)證碼(令牌的一種升級(jí),目前來看破解難度極大),或者要求用戶再次輸入密碼(亞馬遜、淘寶的做法)。但這兩種方式用戶體驗(yàn)都不好,所以需要產(chǎn)品開發(fā)者權(quán)衡。
d.無(wú)論是普通的請(qǐng)求令牌還是驗(yàn)證碼,服務(wù)器端驗(yàn)證過一定記得銷毀。忘記銷毀用過的令牌是個(gè)很低級(jí)但是殺傷力很大的錯(cuò)誤。我們學(xué)校的選課系統(tǒng)就有這個(gè)問題,驗(yàn)證碼用完并未銷毀,故只要獲取一次驗(yàn)證碼圖片,其中的驗(yàn)證碼可以在多次請(qǐng)求中使用(只要不再次刷新驗(yàn)證碼圖片),一直用到。
如下也列出一些據(jù)說能有效防范 CSRF,其實(shí)效果甚微或甚至無(wú)效的做法:
a.通過 referer 判定來源頁(yè)面:referer 是在 HTTP Request Head 里面的,也就是由請(qǐng)求的發(fā)送者決定的。如果我喜歡,可以給 referer 任何值。當(dāng)然這個(gè)做法并不是毫無(wú)作用,起碼可以防小白。但我覺得性價(jià)比不如令牌。
b.過濾所有用戶發(fā)布的鏈接:這個(gè)是最無(wú)效的做法,因?yàn)槭紫裙粽卟灰欢ㄒ獜恼緝?nèi)發(fā)起請(qǐng)求(上面提到過了),而且就算從站內(nèi)發(fā)起請(qǐng)求,途徑也遠(yuǎn)遠(yuǎn)不知鏈接一條。比如
就是個(gè)不錯(cuò)的選擇,還不需要用戶去點(diǎn)擊,只要用戶的瀏覽器會(huì)自動(dòng)加載圖片,就會(huì)自動(dòng)發(fā)起請(qǐng)求。
c.在請(qǐng)求發(fā)起頁(yè)面用 alert 彈窗提醒用戶:這個(gè)方法看上去能干擾站外通過 iframe 發(fā)起的 CSRF,但攻擊者也可以考慮用 window.alert = function(){}; 把 alert 弄啞,或者干脆脫離 iframe,使用 Flash 來達(dá)到目的。
總體來說,目前防御 CSRF 的諸多方法還沒幾個(gè)能徹底無(wú)解的。 作為開發(fā)者,我們能做的就是盡量提高破解難度。當(dāng)破解難度達(dá)到一定程度,網(wǎng)站就逼近于絕對(duì)安全的位置了
參考文獻(xiàn)
[1].Preventing CSRF
[2].Security Corner: Cross-Site Request Forgeries
[3].《Web安全測(cè)試之跨站請(qǐng)求偽造(CSRF)》
[4].百度百科-CSRF、XSS
標(biāo)題名稱:科普:對(duì)于XSS和CSRF你究竟了解多少
標(biāo)題鏈接:http://fisionsoft.com.cn/article/ccseoco.html


咨詢
建站咨詢
