php session劫持和防范的方法
更新時(shí)間:2013年11月12日 11:18:26 作者:
本文介紹php session劫持和防范的方法
session 數(shù)據(jù)暴露
會(huì)話數(shù)據(jù)常會(huì)包含一些個(gè)人信息和其它敏感數(shù)據(jù)?;谶@個(gè)原因,會(huì)話數(shù)據(jù)的暴露是被普遍關(guān)心的問(wèn)題。一般來(lái)說(shuō),暴露的范圍不會(huì)很大,因?yàn)闀?huì)話數(shù)據(jù)是保存在服務(wù)器環(huán)境中的,而不是在數(shù)據(jù)庫(kù)或文件系統(tǒng)中。因此,會(huì)話數(shù)據(jù)自然不會(huì)公開暴露。
使用SSL是一種特別有效的手段,它可以使數(shù)據(jù)在服務(wù)器和客戶端之間傳送時(shí)暴露的可能性降到最低。這對(duì)于傳送敏感數(shù)據(jù)的應(yīng)用來(lái)說(shuō)非常重要。SSL在HTTP之上提供了一個(gè)保護(hù)層,以使所有在HTTP請(qǐng)求和應(yīng)答中的數(shù)據(jù)都得到了保護(hù)。
如果你關(guān)心的是會(huì)話數(shù)據(jù)保存區(qū)本身的安全,你可以對(duì)會(huì)話數(shù)據(jù)進(jìn)行加密,這樣沒有正確的密鑰就無(wú)法讀取它的內(nèi)容。這在PHP中非常容易做到,你只要使用session_set_save_handler( )并寫上你自己的session加密存儲(chǔ)和解密讀取的處理函數(shù)即可。
session 劫持
最常見的針對(duì)會(huì)話的攻擊手段是會(huì)話劫持。它是所有攻擊者可以用來(lái)訪問(wèn)其它人的會(huì)話的手段的總稱。所有這些手段的第一步都是取得一個(gè)合法的會(huì)話標(biāo)識(shí)來(lái)偽裝成合法用戶,因此保證會(huì)話標(biāo)識(shí)不被泄露非常重要。前面關(guān)于會(huì)話暴露和固定的知識(shí)能幫助你保證會(huì)話標(biāo)識(shí)只有服務(wù)器及合法用戶才能知道。
深度防范原則可以用在會(huì)話上,當(dāng)會(huì)話標(biāo)識(shí)不幸被攻擊者知道的情況下,一些不起眼的安全措施也會(huì)提供一些保護(hù)。作為一個(gè)關(guān)心安全的開發(fā)者,你的目標(biāo)應(yīng)該是使前述的偽裝過(guò)程變得更復(fù)雜。記住無(wú)論多小的障礙,都會(huì)以你的應(yīng)用提供保護(hù)。
把偽裝過(guò)程變得更復(fù)雜的關(guān)鍵是加強(qiáng)驗(yàn)證。會(huì)話標(biāo)識(shí)是驗(yàn)證的首要方法,同時(shí)你可以用其它數(shù)據(jù)來(lái)補(bǔ)充它。你可以用的所有數(shù)據(jù)只是在每個(gè)HTTP請(qǐng)求中的數(shù)據(jù):
GET / HTTP/1.1
Host: example.org
User-Agent: Firefox/1.0
Accept: text/html, image/png, image/jpeg, image/gif, */*
Cookie: PHPSESSID=1234
你應(yīng)該意識(shí)到請(qǐng)求的一致性,并把不一致的行為認(rèn)為是可疑行為。例如,雖然User-Agent(發(fā)出本請(qǐng)求的瀏覽器類型)頭部是可選的,但是只要是發(fā)出該頭部的瀏覽器通常都不會(huì)變化它的值。如果你一個(gè)擁有1234的會(huì)話標(biāo)識(shí)的用戶在登錄后一直用Mozilla Firfox瀏覽器,突然轉(zhuǎn)換成了IE,這就比較可疑了。例如,此時(shí)你可以用要求輸入密碼方式來(lái)減輕風(fēng)險(xiǎn),同時(shí)在誤報(bào)時(shí),這也對(duì)合法用戶產(chǎn)生的沖擊也比較小。你可以用下面的代碼來(lái)檢測(cè)User-Agent的一致性:
<?php
session_start();
if (isset($_SESSION['HTTP_USER_AGENT']))
{
if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT']))
{
/* Prompt for password */
exit;
}
}
else
{
$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
}
?>
我觀察過(guò),在某些版本的IE瀏覽器中,用戶正常訪問(wèn)一個(gè)網(wǎng)頁(yè)和刷新一個(gè)網(wǎng)頁(yè)時(shí)發(fā)出的Accept頭部信息不同,因此Accept頭部不能用來(lái)判斷一致性。
確保User-Agent頭部信息一致的確是有效的,但如果會(huì)話標(biāo)識(shí)通過(guò)cookie傳遞(推薦方式),有道理認(rèn)為,如果攻擊者能取得會(huì)話標(biāo)識(shí),他同時(shí)也能取得其它HTTP頭部。由于cookie暴露與瀏覽器漏洞或跨站腳本漏洞相關(guān),受害者需要訪問(wèn)攻擊者的網(wǎng)站并暴露所有頭部信息。所有攻擊者要做的只是重建頭部以防止任何對(duì)頭部信息一致性的檢查。
比較好的方法是產(chǎn)生在URL中傳遞一個(gè)標(biāo)記,可以認(rèn)為這是第二種驗(yàn)證的形式(雖然更弱)。使用這個(gè)方法需要進(jìn)行一些編程工作,PHP中沒有相應(yīng)的功能。例如,假設(shè)標(biāo)記保存在$token中,你需要把它包含在所有你的應(yīng)用的內(nèi)部鏈接中:
<?php
$url = array();
$html = array();
$url['token'] = rawurlencode($token);
$html['token'] = htmlentities($url['token'], ENT_QUOTES, 'UTF-8');
?>
<a href="index.php?token=<?php echo $html['token']; ?>">Click Here</a>
為了更方便地管理這個(gè)傳遞過(guò)程,你可能會(huì)把整個(gè)請(qǐng)求串放在一個(gè)變量中。你可以把這個(gè)變量附加到所有鏈接后面,這樣即便你一開始沒有使用該技巧,今后還是可以很方便地對(duì)你的代碼作出變化。
該標(biāo)記需要包含不可預(yù)測(cè)的內(nèi)容,即便是在攻擊者知道了受害者瀏覽器發(fā)出的HTTP頭部的全部信息也不行。一種方法是生成一個(gè)隨機(jī)串作為標(biāo)記:
<?php
$string = $_SERVER['HTTP_USER_AGENT'];
$string .= 'SHIFLETT';
$token = md5($string);
$_SESSION['token'] = $token;
?>
當(dāng)你使用隨機(jī)串時(shí)(如SHIFLETT),對(duì)它進(jìn)行預(yù)測(cè)是不現(xiàn)實(shí)的。此時(shí),捕獲標(biāo)記將比預(yù)測(cè)標(biāo)記更為方便,通過(guò)在URL中傳遞標(biāo)記和在cookie中傳遞會(huì)話標(biāo)識(shí),攻擊時(shí)需要同時(shí)抓取它們二者。這樣除非攻擊者能夠察看受害者發(fā)往你的應(yīng)用所有的HTTP請(qǐng)求原始信息才可以,因?yàn)樵谶@種情況下所有內(nèi)容都暴露了。這種攻擊方式實(shí)現(xiàn)起來(lái)非常困難(所以很罕見),要防止它需要使用SSL。
有專家警告不要依賴于檢查User-Agent的一致性。這是因?yàn)榉?wù)器群集中的HTTP代理服務(wù)器會(huì)對(duì)User-Agent進(jìn)行編輯,而本群集中的多個(gè)代理服務(wù)器在編輯該值時(shí)可能會(huì)不一致。如果你不希望依賴于檢查User-Agent的一致性。你可以生成一個(gè)隨機(jī)的標(biāo)記:
<?php
$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
?>
這一方法的安全性雖然是弱一些,但它更可靠。上面的兩個(gè)方法都對(duì)防止會(huì)話劫持提供了強(qiáng)有力的手段。你需要做的是在安全性和可靠性之間作出平衡。
會(huì)話數(shù)據(jù)常會(huì)包含一些個(gè)人信息和其它敏感數(shù)據(jù)?;谶@個(gè)原因,會(huì)話數(shù)據(jù)的暴露是被普遍關(guān)心的問(wèn)題。一般來(lái)說(shuō),暴露的范圍不會(huì)很大,因?yàn)闀?huì)話數(shù)據(jù)是保存在服務(wù)器環(huán)境中的,而不是在數(shù)據(jù)庫(kù)或文件系統(tǒng)中。因此,會(huì)話數(shù)據(jù)自然不會(huì)公開暴露。
使用SSL是一種特別有效的手段,它可以使數(shù)據(jù)在服務(wù)器和客戶端之間傳送時(shí)暴露的可能性降到最低。這對(duì)于傳送敏感數(shù)據(jù)的應(yīng)用來(lái)說(shuō)非常重要。SSL在HTTP之上提供了一個(gè)保護(hù)層,以使所有在HTTP請(qǐng)求和應(yīng)答中的數(shù)據(jù)都得到了保護(hù)。
如果你關(guān)心的是會(huì)話數(shù)據(jù)保存區(qū)本身的安全,你可以對(duì)會(huì)話數(shù)據(jù)進(jìn)行加密,這樣沒有正確的密鑰就無(wú)法讀取它的內(nèi)容。這在PHP中非常容易做到,你只要使用session_set_save_handler( )并寫上你自己的session加密存儲(chǔ)和解密讀取的處理函數(shù)即可。
session 劫持
最常見的針對(duì)會(huì)話的攻擊手段是會(huì)話劫持。它是所有攻擊者可以用來(lái)訪問(wèn)其它人的會(huì)話的手段的總稱。所有這些手段的第一步都是取得一個(gè)合法的會(huì)話標(biāo)識(shí)來(lái)偽裝成合法用戶,因此保證會(huì)話標(biāo)識(shí)不被泄露非常重要。前面關(guān)于會(huì)話暴露和固定的知識(shí)能幫助你保證會(huì)話標(biāo)識(shí)只有服務(wù)器及合法用戶才能知道。
深度防范原則可以用在會(huì)話上,當(dāng)會(huì)話標(biāo)識(shí)不幸被攻擊者知道的情況下,一些不起眼的安全措施也會(huì)提供一些保護(hù)。作為一個(gè)關(guān)心安全的開發(fā)者,你的目標(biāo)應(yīng)該是使前述的偽裝過(guò)程變得更復(fù)雜。記住無(wú)論多小的障礙,都會(huì)以你的應(yīng)用提供保護(hù)。
把偽裝過(guò)程變得更復(fù)雜的關(guān)鍵是加強(qiáng)驗(yàn)證。會(huì)話標(biāo)識(shí)是驗(yàn)證的首要方法,同時(shí)你可以用其它數(shù)據(jù)來(lái)補(bǔ)充它。你可以用的所有數(shù)據(jù)只是在每個(gè)HTTP請(qǐng)求中的數(shù)據(jù):
GET / HTTP/1.1
Host: example.org
User-Agent: Firefox/1.0
Accept: text/html, image/png, image/jpeg, image/gif, */*
Cookie: PHPSESSID=1234
你應(yīng)該意識(shí)到請(qǐng)求的一致性,并把不一致的行為認(rèn)為是可疑行為。例如,雖然User-Agent(發(fā)出本請(qǐng)求的瀏覽器類型)頭部是可選的,但是只要是發(fā)出該頭部的瀏覽器通常都不會(huì)變化它的值。如果你一個(gè)擁有1234的會(huì)話標(biāo)識(shí)的用戶在登錄后一直用Mozilla Firfox瀏覽器,突然轉(zhuǎn)換成了IE,這就比較可疑了。例如,此時(shí)你可以用要求輸入密碼方式來(lái)減輕風(fēng)險(xiǎn),同時(shí)在誤報(bào)時(shí),這也對(duì)合法用戶產(chǎn)生的沖擊也比較小。你可以用下面的代碼來(lái)檢測(cè)User-Agent的一致性:
復(fù)制代碼 代碼如下:
<?php
session_start();
if (isset($_SESSION['HTTP_USER_AGENT']))
{
if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT']))
{
/* Prompt for password */
exit;
}
}
else
{
$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
}
?>
我觀察過(guò),在某些版本的IE瀏覽器中,用戶正常訪問(wèn)一個(gè)網(wǎng)頁(yè)和刷新一個(gè)網(wǎng)頁(yè)時(shí)發(fā)出的Accept頭部信息不同,因此Accept頭部不能用來(lái)判斷一致性。
確保User-Agent頭部信息一致的確是有效的,但如果會(huì)話標(biāo)識(shí)通過(guò)cookie傳遞(推薦方式),有道理認(rèn)為,如果攻擊者能取得會(huì)話標(biāo)識(shí),他同時(shí)也能取得其它HTTP頭部。由于cookie暴露與瀏覽器漏洞或跨站腳本漏洞相關(guān),受害者需要訪問(wèn)攻擊者的網(wǎng)站并暴露所有頭部信息。所有攻擊者要做的只是重建頭部以防止任何對(duì)頭部信息一致性的檢查。
比較好的方法是產(chǎn)生在URL中傳遞一個(gè)標(biāo)記,可以認(rèn)為這是第二種驗(yàn)證的形式(雖然更弱)。使用這個(gè)方法需要進(jìn)行一些編程工作,PHP中沒有相應(yīng)的功能。例如,假設(shè)標(biāo)記保存在$token中,你需要把它包含在所有你的應(yīng)用的內(nèi)部鏈接中:
復(fù)制代碼 代碼如下:
<?php
$url = array();
$html = array();
$url['token'] = rawurlencode($token);
$html['token'] = htmlentities($url['token'], ENT_QUOTES, 'UTF-8');
?>
<a href="index.php?token=<?php echo $html['token']; ?>">Click Here</a>
為了更方便地管理這個(gè)傳遞過(guò)程,你可能會(huì)把整個(gè)請(qǐng)求串放在一個(gè)變量中。你可以把這個(gè)變量附加到所有鏈接后面,這樣即便你一開始沒有使用該技巧,今后還是可以很方便地對(duì)你的代碼作出變化。
該標(biāo)記需要包含不可預(yù)測(cè)的內(nèi)容,即便是在攻擊者知道了受害者瀏覽器發(fā)出的HTTP頭部的全部信息也不行。一種方法是生成一個(gè)隨機(jī)串作為標(biāo)記:
復(fù)制代碼 代碼如下:
<?php
$string = $_SERVER['HTTP_USER_AGENT'];
$string .= 'SHIFLETT';
$token = md5($string);
$_SESSION['token'] = $token;
?>
當(dāng)你使用隨機(jī)串時(shí)(如SHIFLETT),對(duì)它進(jìn)行預(yù)測(cè)是不現(xiàn)實(shí)的。此時(shí),捕獲標(biāo)記將比預(yù)測(cè)標(biāo)記更為方便,通過(guò)在URL中傳遞標(biāo)記和在cookie中傳遞會(huì)話標(biāo)識(shí),攻擊時(shí)需要同時(shí)抓取它們二者。這樣除非攻擊者能夠察看受害者發(fā)往你的應(yīng)用所有的HTTP請(qǐng)求原始信息才可以,因?yàn)樵谶@種情況下所有內(nèi)容都暴露了。這種攻擊方式實(shí)現(xiàn)起來(lái)非常困難(所以很罕見),要防止它需要使用SSL。
有專家警告不要依賴于檢查User-Agent的一致性。這是因?yàn)榉?wù)器群集中的HTTP代理服務(wù)器會(huì)對(duì)User-Agent進(jìn)行編輯,而本群集中的多個(gè)代理服務(wù)器在編輯該值時(shí)可能會(huì)不一致。如果你不希望依賴于檢查User-Agent的一致性。你可以生成一個(gè)隨機(jī)的標(biāo)記:
復(fù)制代碼 代碼如下:
<?php
$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
?>
這一方法的安全性雖然是弱一些,但它更可靠。上面的兩個(gè)方法都對(duì)防止會(huì)話劫持提供了強(qiáng)有力的手段。你需要做的是在安全性和可靠性之間作出平衡。
您可能感興趣的文章:
- php設(shè)置session值和cookies的學(xué)習(xí)示例
- PHP中session變量的銷毀
- php中session退出登陸問(wèn)題
- php把session寫入數(shù)據(jù)庫(kù)示例
- php將session放入memcached的設(shè)置方法
- php環(huán)境下利用session防止頁(yè)面重復(fù)刷新的具體實(shí)現(xiàn)
- PHP修改session_id示例代碼
- php5.3 不支持 session_register() 此函數(shù)已啟用的解決方法
- session在php5.3中的變化 session_is_registered() is deprecated in
- php Session存儲(chǔ)到Redis的方法
- 教你如何使用php session
- php session_start()出錯(cuò)原因分析及解決方法
- PHP關(guān)于IE下的iframe跨域?qū)е聅ession丟失問(wèn)題解決方法
- PHP Session 變量的使用方法詳解與實(shí)例代碼
- PHP中怎樣保持SESSION不過(guò)期 原理及方案介紹
- 注意:php5.4刪除了session_unregister函數(shù)
- PHP session_start()問(wèn)題解疑(詳細(xì)介紹)
- php中session使用示例
相關(guān)文章
PHP數(shù)組操作——獲取數(shù)組最后一個(gè)值的方法
這篇文章主要介紹了PHP數(shù)組操作——獲取數(shù)組最后一個(gè)值的方法,需要的朋友可以參考下2015-04-04php環(huán)境配置 php5 mysql5 apache2 phpmyadmin安裝與配置
php環(huán)境配置 php5 mysql5 apache2 phpmyadmin安裝與配置...2006-11-11php讀取torrent種子文件內(nèi)容的方法(測(cè)試可用)
這篇文章主要介紹了php讀取torrent種子文件內(nèi)容的方法,可實(shí)現(xiàn)讀取并顯示torrent種子文件內(nèi)容的功能,簡(jiǎn)單實(shí)用,需要的朋友可以參考下2016-05-05php+js實(shí)現(xiàn)的無(wú)刷新下載文件功能示例
這篇文章主要介紹了php+js實(shí)現(xiàn)的無(wú)刷新下載文件功能,結(jié)合實(shí)例形式分析了php無(wú)刷新下載文件的相關(guān)原理、實(shí)現(xiàn)方法及操作注意事項(xiàng),需要的朋友可以參考下2019-08-08php實(shí)現(xiàn)簡(jiǎn)單的上傳進(jìn)度條
大家在上傳文件時(shí)都會(huì)看到一個(gè)非常精致的進(jìn)度條,從進(jìn)度條上我們很直觀的可以看到文件、圖片上傳進(jìn)度,本文分享了php實(shí)現(xiàn)簡(jiǎn)單的上傳進(jìn)度條,感興趣的小伙伴們可以參考一下。2015-11-11PHP實(shí)現(xiàn)登錄的Cookie存儲(chǔ)方案詳解
這篇文章主要介紹了PHP實(shí)現(xiàn)登錄的Cookie存儲(chǔ)方案詳解的相關(guān)資料,需要的朋友可以參考下2023-02-02