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