■ 河南 郭建偉
編者按:在Web應(yīng)用環(huán)境中,當(dāng)用戶登錄后會執(zhí)行一些關(guān)鍵性的處理操作(一旦完成則無法撤銷),如在線支付、修改密碼、發(fā)送E-mail等。如果在這些關(guān)鍵處理中存在安全問題,其危害是不可小視的。例如,跨站請求偽造(CSRF)就是針對關(guān)鍵處理環(huán)節(jié)進行攻擊的。
對于XSS攻擊來說,黑客可以盜取用戶的Cookie信息,并利用其登錄網(wǎng)站,執(zhí)行常規(guī)操作(例如瀏覽、添加購物車等),但是卻無法執(zhí)行付款等關(guān)鍵操作。
為了防御上述攻擊,在執(zhí)行關(guān)鍵操作之前,必須確認(rèn)請求是由真正的用戶自愿發(fā)起的才行。如果該環(huán)節(jié)被忽視,就很容易引發(fā)安全問題。例如,當(dāng)用戶誤入某個惡意網(wǎng)站后,瀏覽器就擅自執(zhí)行修改郵箱密碼等關(guān)鍵操作,對于此類非法操作要必須禁止。
一旦黑客利用CSRF漏洞攻擊得手的話,就會利用用戶賬號進行在線購物、刪除用戶賬號、隨意發(fā)布信息以及非法修改用戶密碼等操作,給用戶造成不小的危害。當(dāng)然,CSRF漏洞影響僅僅限于Web應(yīng)用的關(guān)鍵處理被惡意利用而已,對于用戶的隱私信息等內(nèi)容是無法盜取的。
任意網(wǎng)站都可能存在執(zhí)行關(guān)鍵處理的Web頁面。例如,僅僅使用Cookie進行會話管理,僅僅使用HTTP認(rèn)證,SSL客戶端認(rèn)證以及手機移動ID來識別用戶身份等網(wǎng)站來說,都有可能遭到黑客的CSRF攻擊。
必須在關(guān)鍵頁面添加關(guān)鍵性的認(rèn)證,才可以有效抵御此類攻擊。黑客在實施此類攻擊時,經(jīng)常會使用釣魚等手法,來引誘用戶點擊惡意鏈接,使其進入惡意站點,觸發(fā)黑客預(yù)設(shè)的惡意程序進行攻擊。
最有效的應(yīng)對策略其實很簡單,就是在執(zhí)行關(guān)鍵處理之前,一定要確認(rèn)這是合法用戶發(fā)起的請求。
CSRF攻擊常見的有兩種攻擊方式,第一種攻擊是輸入特定的數(shù)據(jù)(例如密碼)后,執(zhí)行攻擊操作。例如,某個合法用戶已經(jīng)登錄了某個網(wǎng)站,在用戶本機中就會保存相應(yīng)的Cookie信息,可以保持登錄的狀態(tài)。黑客只需“精心”編輯一個網(wǎng)頁,在其中內(nèi)嵌訪問該網(wǎng)站特定的頁面(例如修改密碼等)的語句,并將其偽裝成看似合法的鏈接,來引誘用戶點擊,當(dāng)合法的用戶誤擊該鏈接后,黑客就可以毫不費力的自動向目標(biāo)網(wǎng)站發(fā)送相應(yīng)的POST請求,來順利完成特定的操作(例如修改用戶密碼等)。
當(dāng)然,黑客在發(fā)送時會附帶包含會話ID的Cookie信息。應(yīng)該指出,根據(jù)同源策略,從惡意網(wǎng)頁所在iFrame的外層是無法讀取到目標(biāo)網(wǎng)站內(nèi)層的信息的。
所以CSRF攻擊雖然能夠以合法用戶的身份惡意使用目標(biāo)網(wǎng)站的關(guān)鍵處理程序,但是卻無法顯示目標(biāo)網(wǎng)頁的內(nèi)容。即便如此,如果黑客攻擊得手,例如修改了用戶的密碼后,是可以據(jù)此登錄網(wǎng)站,來獲取更多的用戶信息的。
第二種攻擊方式是在上述基礎(chǔ)上包含確認(rèn)頁面的攻擊行為,例如,在修改密碼時顯示確認(rèn)頁面等。對于確認(rèn)頁面來說,將數(shù)據(jù)傳送給執(zhí)行頁面有兩種方式,即使用hidden參數(shù)和使用會話變量。所謂hidden參數(shù),指的是類型為hidden的input元素。黑客在惡意頁面中內(nèi)嵌了“onload”“action”等語句,將隱藏參數(shù)通過Post方法,傳遞給執(zhí)行頁面。該隱含參數(shù)是由客戶發(fā)送給目標(biāo)服務(wù)器的。
為了防止上述隱含參數(shù)被修改,黑客還會使用會話變量的方式進行攻擊,因為會話變量的內(nèi)容是保存在服務(wù)器端的,無法被用戶修改,即先讓用戶確認(rèn)要修改的內(nèi)容(例如郵箱等),之后將其內(nèi)容存儲到指定的會話變量中。
當(dāng)用戶點擊了惡意鏈接執(zhí)行提交操作時,惡意程序就可以根據(jù)用戶的會話ID,從服務(wù)器端讀取該變量的值,來執(zhí)行關(guān)鍵處理操作。例如修改用戶的郵箱密碼等。
這種攻擊手法實際上是比較狡猾的,現(xiàn)在逐漸成為了CSRF攻擊的主要形式。黑客會在惡意網(wǎng)站中嵌入兩個iFrame框架,其中一個的隨著惡意頁面的打開立即執(zhí)行,會向確認(rèn)頁面發(fā)送包含要更改信息(例如密碼)的Post請求,只要該信息就會保存到會話變量中,稍后另外一個iFrame會自動打開執(zhí)行頁面完成CSRF攻擊動作,因為需要更改的信息已經(jīng)保存到了會話變量中,所以黑客可以毫不費力的對其進行更改。
有些網(wǎng)站在執(zhí)行更改操作時,可能會使用向?qū)У姆绞剑?jīng)過一系列步驟才能執(zhí)行關(guān)鍵動作。黑客只需增加iFrame的數(shù)量,就可以很輕松的完成攻擊操作。
從這個意義上說,CSRF攻擊所惡意使用的關(guān)鍵處理程序是目標(biāo)服務(wù)器提供的,XSS攻擊的情形與之是不同的。
對于XSS攻擊來說,當(dāng)用戶誤入惡意站點后,其會推送惡意腳本給用戶,該惡意腳本是在用戶的瀏覽器中執(zhí)行的,這樣黑客就可以利用用戶的瀏覽器執(zhí)行各種非法操作。黑客甚至還可以借此向目標(biāo)服務(wù)器發(fā)出惡意請求,并且將包含惡意信息的內(nèi)容名反彈給黑客。
因此說,XSS攻擊的危害性要比CSRF要大。要想防御CSRF攻擊,最關(guān)鍵的方法是確認(rèn)關(guān)鍵處理的請求是有合法的用戶自愿發(fā)起的。應(yīng)對方法包括篩選出需要防范CSFR攻擊的頁面,以及讓程序具有辨認(rèn)是否由合規(guī)用戶資源發(fā)起的能力等。
當(dāng)然,并非所有的頁面都需要防御CSRF攻擊,實際上大多數(shù)的頁面無需防范這類攻擊。例如,對在線購物網(wǎng)站來說,其可以通過各種鏈接進入網(wǎng)站,這便于用戶自由出入,對于這些外部鏈接來說,是無需實施CSRF防護的。
只能對網(wǎng)站中諸如付款頁面、用戶登錄、密碼修改等重要環(huán)節(jié),不能任由來歷不明的用戶隨意操作,必須對其進行CSRF防護處理。例如,對于修改信息頁面來說,常常的操作是由合法的用戶輸入各種信息,之后點擊確認(rèn)按鈕執(zhí)行修改動作。
CSRF攻擊實際上沒有經(jīng)歷以上操作,只是通過iFrame發(fā)送非法請求,來完成信息的修改。判斷其是否合規(guī)的方法有多種,包括嵌入機密信息利用令牌進行判斷,多次輸入密碼以及檢驗Referer信息等。
對于這三種攻擊的防御方式來說,可謂各具特點。第一種方法對用戶的操作是沒有影響的,是最基本的防御策略。第二種方法增加了用戶操作的復(fù)雜度,具有安全性最高的特點。這兩種方式對手機網(wǎng)站均可以支持。對于第三種來說,如果用戶的瀏覽器關(guān)閉了Referer功能的話,就無法發(fā)揮作用了,而且其不可應(yīng)用于手機網(wǎng)站,只能作為輔助方式使用。
上面談到,根據(jù)同源策略,從惡意網(wǎng)頁所在iFrame的外層是無法讀取到目標(biāo)網(wǎng)站內(nèi)層的信息的,因此可以給合法客戶發(fā)送一次性的令牌(即隨機數(shù)),黑客就無法讀取該令牌,據(jù)此可以判斷請求是否合法。
利用再次輸入密碼,或發(fā)送隨機密碼進行確認(rèn)等操作,也可以有效防御CSRF攻擊。因為黑客誘使用戶進入惡意頁面,之后才能發(fā)起CSRF攻擊,從一個頁面鏈接到另外的頁面,客戶瀏覽器會產(chǎn)生Referer屬性值,包含源頁面信息。對Referer的值進行檢測,可以準(zhǔn)確判斷出是否有惡意站點鏈接過來的。
當(dāng)訪問需要保護的關(guān)鍵處理頁面時,處于安全性考慮,需要提供第三方無法知曉的機密信息,那么即使黑客冒充合法用戶發(fā)送請求的話,應(yīng)用端也可以據(jù)此判斷該請求的合法性。實現(xiàn)上述功能的機密信息就成為令牌,例如,可以將會話ID作為令牌。
例如,在頁面中添加“”等語句,將會話ID作為令牌使用。這樣,黑客是無法讀取該令牌內(nèi)容的。在接收令牌時,必須使用POST方法,例如使用“if (session_id() !==$_POST['token'])”,“{die ('該請求不合法,是可疑的攻擊行為')}”等語句來讀取令牌。
如果使用了GET方法發(fā)送令牌的話,就會通過客戶端瀏覽器的Referer參數(shù)泄露出去。這樣,當(dāng)黑客試圖發(fā)起CSRF攻擊時,就會因為無法提供令牌信息就服務(wù)器拒絕。
對于合法的用戶操作來說,因為可以提供正確的令牌值,所以是不會進行攔截的。對于要求不高的場合,該方法是可以滿足需求的。
對于安全性要求比較高的網(wǎng)站來說,可以使用再次要求用戶輸入密碼,或者向其手機發(fā)送一次性驗證碼的方式,來確認(rèn)用戶的真實身份,而且可以再次確定用戶是否執(zhí)行提交訂單等操作。當(dāng)然,不管應(yīng)對哪一種CSRF攻擊方式,再次輸入密碼進行驗證必須在最后的執(zhí)行頁面前的那一刻進行方可,即再次要求數(shù)據(jù)密碼的時機是很重要的。因為僅僅在之前的某個頁面進行驗證,依然可能存在CSRF漏洞的。
利用檢驗Referer值的方法,可以有效檢測請求的原來是否合法,例如,從上一個合法頁面轉(zhuǎn)過來的話,是可以進行處理的。如果是從惡意網(wǎng)站鏈接過來的,則使其為非法。
在網(wǎng)頁中嵌入諸如“if(preg_match('#/Ahttp://www.xxx.com/reque/hefa.php#',@$_SERVER['HTTP_REFERER']) !==1){die ('非法的請求');}”之類的語句,確認(rèn)當(dāng)前的請求中的Referer的值必須為執(zhí)行頁面上一個頁面的地址。這里 的“www.xxx.com/reque/hefa”為假設(shè)的頁面地址,表示請求必須從該地址中來的才行。在實際應(yīng)用中可以根據(jù)需要進行調(diào)整,在其地址中保存了所需的PHP文件。
當(dāng)然,如果將檢測Referer值和檢測上述令牌值的方法結(jié)合起來使用,就可以大大提高防范CSRF攻擊的能力。
僅僅采用以上防御方式還是不能完全滿足實際需要,在執(zhí)行了關(guān)鍵處理操作后,最好向用戶的郵箱或手機發(fā)送有關(guān)處理內(nèi)容的通知信息,讓用戶可以在第一時間知曉相關(guān)信息,即使黑客利用XSS或CSRF方式攻擊得手,用戶也可以及時洞察并采取各種措施(例如凍結(jié)賬戶等),將損失將至最低。
注意,在通知中不要包含敏感信息,因為發(fā)送的方式(例如郵件等)可能是不加密的,讓用戶登錄到指定的Web頁面,來詳細(xì)查看諸如購買記錄、密碼變更等詳細(xì)情況。