■ 河南 郭建偉
可以說,會話ID的作用極為關(guān)鍵,正因為該會話ID的重要性,因此也成了黑客“關(guān)注”的目標(biāo)。
如果某合法用戶的會話ID被黑客獲取,黑客就會偽裝成該用戶來非法訪問Web應(yīng)用,這種攻擊手段被稱為會話劫持。
因此,對于會話ID進行保護就顯得極為重要。黑客獲取會話ID的方法包括預(yù)測會話ID、竊取會話ID和挾持會話ID等。
對于第一種攻擊方式來說,黑客可以采取猜測的方法來獲知會話ID。
對于第二種攻擊方式來說,黑客可以嗅探HTTP明文信息來獲取會話ID。
當(dāng)然,黑客還可能會利用XSS跨站腳本,以及HTTP消息頭注入,或者將會話ID嵌入到URL等手段,來竊取會話ID。
對于第三種攻擊方式來說,黑客可以先獲取一個屬于自己的會話ID,之后便強制其他用戶使用該ID來連接Web應(yīng)用。即黑客通過各種欺騙手段,將指定的會話ID強制設(shè)置到用戶的瀏覽器之中,然后就可以輕松掌控用戶的會話ID,以造成會話劫持,這也被稱為固定會話攻擊。
對于預(yù)測會話ID來說,其實是一個Web設(shè)計上的缺陷。如果生成會話ID的方法不完善,用戶的會話ID就很可能被黑客成功預(yù)測,黑客進而就可以劫持會話。
例如,基于連續(xù)的數(shù)值、固定的日期時間,以及用戶名稱等方式來產(chǎn)生會話ID的話,就會造成安全隱患。此外,使用一些開源軟件來生成會話ID的話,因為對用的程序邏輯實際上處于開放狀態(tài),因此黑客根據(jù)公開的代碼也完全可以推測出會話ID。
因此,必須使用絕對的隨機數(shù)來生成會話ID,為了避免可預(yù)測的會話ID,應(yīng)該避免自行開發(fā)相關(guān)的會話管理機制。最穩(wěn)妥的辦法是使用成型的框架(例如,PHP、Java/J2EE、ASP.NET等編程語言或者中間件)提供的會話管理機制,來創(chuàng)建完全隨機的會話ID。對于預(yù)測會話ID漏洞而言,其影響的范圍包括使用會話的所有頁面,尤其對于顯示隱私信息或者執(zhí)行關(guān)鍵處理(例如,購物、發(fā)帖、更改密碼等)的頁面來說,其危害尤為明顯。
注意,該攻擊方式是無需用戶參與的。具體的應(yīng)對方法也很簡單,即不要自行設(shè)計會話管理機制,必須使用功能強大的Web應(yīng)用開發(fā)工具內(nèi)置的會話管理機制。對于此類機制來說,會將用戶的ID、IP地址、日期和時間以及隨機數(shù)等內(nèi)容組合起來使用,執(zhí)行加密或者散列函數(shù)處理,來得到會話ID,其安全性較高,往往是難以預(yù)測的。
黑客可以使用各種方法來竊取會話ID,例如,對于會話ID嵌入URL來說,會話ID并不保存在Cookie中,而是保存在URL中。PHP、Jave以及ASP.NET等工具都支持該功能。此外,在手機中也可能采用該方法來訪問Web應(yīng)用。
但是,該方式存在很大的安全隱患,可能造成會話ID經(jīng)由Referer消息頭泄露。例如,黑客可先在侵入某個合法的網(wǎng)站,之后在其中添加惡意鏈接指向非法網(wǎng)站。
而當(dāng)合法的用戶點擊該惡意鏈接時,用戶當(dāng)前的URL中的會話ID就會被發(fā)送給該非法網(wǎng)站。這樣,黑客就可以很輕松地讀取該非法網(wǎng)站收集的會話ID信息。
當(dāng)然,由Referer造成的會話ID泄露可能是偶發(fā)事件而觸發(fā),也可能是黑客有意為之。為了防止由此引發(fā)的偽裝攻擊,需要在Web程序中禁止將會話ID嵌入到URL中。
注意,該攻擊方式需要用戶參與。例如,對于PHP來說,執(zhí)行“vim php.ini”命令,在編輯界面中將其中的“session.use_cookies=” “session.use_only_cookies=”行的值均設(shè)置為“On”,表示僅僅將會話ID保存到Cookie中。
如果將前者設(shè)置為“On”,將后者設(shè)置為“Off”,那么表示在可以使用Cookie時,將會話ID保存到Cookie中,否則將會話ID嵌入到URL中。為了安全起見,最好使用前者的組合方式。
之后執(zhí)行“service httprestart”命令,重啟Apache服務(wù)讓上述修改生效。
該方法是全局性質(zhì)的針對整個網(wǎng)站發(fā)揮作用,如果僅僅希望在網(wǎng)站的某個目錄下實現(xiàn)上述功能,可以在該目錄下創(chuàng)建名為“.htaccess”的文件,并在其中輸入“php_flag session.use_cookies On” “php_flag.session.use_only_cookies On”行即可。
挾持會話ID攻擊的特點是從外部劫持會話ID,黑客會先取得會話ID,該會話ID是合法的。之后將該會話ID強制提交給給受害用戶,再讓受害用戶登錄黑客需要攻擊的Web應(yīng)用,最后黑客使用該會話ID順利進入目標(biāo)應(yīng)用。
例如,PHP網(wǎng)站如果存在會話ID嵌入URL漏洞,黑客可以在提交URL時,隨意指定一個會話ID來進行攻擊。
因為PHP存在會話采納機制,能夠接受來源不明的會話ID。而對于ASP.NET來說,也存在會話采納機制。對于不存在會話采納機制的中間件上運行的Web程序程序,當(dāng)黑客對其進行攻擊時,會先瀏覽目標(biāo)Web應(yīng)用,來取得有效的會話ID,之后利用該會話ID來布設(shè)惡意鏈接來欺騙用戶。
因此,不管開發(fā)工具中是否存在會話采納機制,都不能完全避免固定會話攻擊。
根據(jù)其攻擊步驟來看,最好的防御方法是在用戶登錄時更換其會話ID,這樣黑客即使按照上述步驟行動,也無法得到用戶登錄后的真實會話ID。
例如,對于PHP來說,就可以使用“session_regenerate_id”函數(shù),來執(zhí)行更改會話ID操作,比如在認(rèn)證后的網(wǎng)頁代碼中添加“session_regenerate_id(true)”行,來生成全新的會話ID,刪除老的會話ID,其中的“true”蠶食用來指定是否將變更前的會話ID對應(yīng)的會話信息刪除。
之后再將用戶提交的信息,例如用戶名、密碼和郵箱等信息寫入到對應(yīng)的會話變量中。因為老的會話ID已經(jīng)消失,所以黑客發(fā)起的固定會話ID攻擊就失敗了。
對于有些Web應(yīng)用來說,因為其使用的開發(fā)工具的原因,無法在程序中顯式的更改會話ID,所以可以使用令牌來防范固定會話攻擊。
其實現(xiàn)方法是在登錄時生成一個隨機數(shù)字字符串(即令牌),將其保存到Cookie和會話變量中,之后在各頁面進行認(rèn)證時比較上述令牌值,如果相符就視為已認(rèn)證狀態(tài),否則視為認(rèn)證錯誤。
因為只有在登錄時,令牌才可以被傳到外界,黑客無法得知該令牌,所以使用令牌可以有效防御固定會話攻擊。例如,在網(wǎng)頁代碼中添加如下命令,設(shè)置產(chǎn)生隨機數(shù)的函數(shù):
之后,添加“$token=getToken()”行,來產(chǎn)生隨機數(shù)(即令牌)。添加“setcookie('token',$token,0,'/');” “$_SESSION ['token']=$token;”行,將令牌保存到Cookie和會話變量中。
這樣,合法用戶可以利用Cookie來獲取該令牌。之后可以利用該令牌進行身份驗證。
例如在對應(yīng)的頁面中添加:
就可以執(zhí)行令牌比對操作,即從用戶提交的Cookie中取得令牌,和會話變量中讀取的令牌進行比對,如果一致則說明用戶合法。黑客雖然可以利用固定會話進行攻擊,但是無法得到該令牌,所以無法進行有效的身份驗證操作。
而對于有些Web網(wǎng)站(尤其是購物網(wǎng)站)可能在登錄前就使用了會話變量,在這種情況下,要想完全防御固定會話攻擊是比較困難的。比較穩(wěn)妥的對策是,在登錄前不要使用會話管理機制,而使用Hidden參數(shù)來傳遞值。
當(dāng)然,為了更好地提高安全性,可以采取各種方式來加以防范,例如,不要在登錄前的會話變量中保存敏感信息,不使用嵌入會話ID的URL,不要使用地域型域名等。