PHP session會話的安全性分析
更新時(shí)間:2011年09月08日 15:25:16 作者:
會話的用途常常是幫助用戶在Web應(yīng)用程序的各個(gè)部分之間跳轉(zhuǎn),(這句話說的比較不全面,其實(shí)主要是為了能共享數(shù)據(jù)。)
從而達(dá)到方便快捷的目的,但是它在存儲信息的時(shí)候往往會有一些敏感的東西,這些東西可能成為被攻擊的目標(biāo),如銀行的賬號、信用卡事務(wù)或檔案記錄等。這就要求在編寫代碼的時(shí)候必須采取安全措施來減少攻擊成功的可能性。
主要的安全措施有以下兩個(gè)方面。
1、防止攻擊者獲取用戶的會話ID。
獲取會話ID的方式很多,攻擊者可以通過查看明文通信來獲取,所以把會話ID放在URL中或者放在通過未加密連接傳輸?shù)腃ookie中是很危險(xiǎn)的;還有在URL中(作為_get()參數(shù))傳遞會話ID也是不安全的,因?yàn)闉g覽器歷史緩存中會存儲URL,這樣就很容易被讀取。(可以考慮使用ssh進(jìn)行加密傳輸)
還有一種更為隱蔽的攻擊手段,攻擊者通過一個(gè)被腳本攻擊突破的Web站點(diǎn),把被突破的這個(gè)站點(diǎn)上的用戶重新定向到另一個(gè)站點(diǎn),然后在重新定向的站點(diǎn)的URL中插入以下代碼:
?PHPSESSID=213456465412312365465412312;
最后發(fā)送到Web應(yīng)用程序。當(dāng)用戶查看Web應(yīng)用程序時(shí),PHP會發(fā)現(xiàn)沒有與這個(gè)會話ID相關(guān)聯(lián)的數(shù)據(jù)并且會創(chuàng)建一些數(shù)據(jù)。用戶不知道發(fā)生了什么,但攻擊者卻知道了會話ID,就可以利用這個(gè)會話ID進(jìn)入應(yīng)用程序。
要防止這種攻擊,有兩種方法。
(1)檢查php.ini中是否打開了session.use_only_cookie。如果是這種情況,PHP會拒絕基于URL的會話ID。
(2)當(dāng)啟動會話時(shí),在會話數(shù)據(jù)中放一個(gè)變量,這個(gè)變量表示會話是用戶創(chuàng)建的;如果發(fā)現(xiàn)會話數(shù)據(jù)中沒有這個(gè)變量,那就說明會話ID是假的,就可以調(diào)用session_regenerate_id函數(shù),給現(xiàn)有會話分配一個(gè)新的會話ID。
示例:
通過判斷變量是否存在來確定會話ID的真假,如果存在,則說明會話ID是真的,否則是假的,并使用session_regenerate_id()函數(shù)對會話ID進(jìn)行更改,重新給會話創(chuàng)建一個(gè)新的會話ID,
代碼如下:
< ?php
session_start () ;
if (!isset ( $_SESSION['shili1'] )) { //判斷shili1變量是否配置
$old_id = session_id () ; //原來的會話ID的變量名
session_regenerate_id () ; //獲取一個(gè)新的會話ID
$new_id = session_id () ; //新的會話ID的變量名
echo "old : $old_id<br/>" ; //輸出原來的會話ID
echo "new : $new_id<br/>" ; //輸出新的會話ID
$_SESSION['shili1'] = TRUE ; }
?>
運(yùn)行結(jié)果如圖所示:

這只是一個(gè)示例,輸出會話ID是為了更好的理解和應(yīng)用這個(gè)函數(shù),而在程序設(shè)計(jì)中是不需要輸出會話ID的。
2、限制攻擊者獲取會話ID。
限制攻擊者獲取會話ID的方法如下。
(1)使用一個(gè)函數(shù)(md5)計(jì)算User-Agent頭加上某些附加字符串?dāng)?shù)據(jù)后的散列值(hash)。(散列函數(shù)(hash function)接受一個(gè)任意大的數(shù)據(jù)集,并且將它轉(zhuǎn)換為一個(gè)看起來完全不同的數(shù)據(jù),這個(gè)數(shù)據(jù)很短。產(chǎn)生的散列值是完全不可重現(xiàn)的,也不可能由另一個(gè)輸入產(chǎn)生。)
在User-Agent字符串后面添加一些數(shù)據(jù),攻擊者就無法通過對常見的代理值計(jì)算md5編碼來試探User-Agent字符串。
(2)將這個(gè)經(jīng)過編碼的字符串保存在用戶的會話數(shù)據(jù)中。
(3)每次從這個(gè)用戶接收到請求時(shí),檢查這個(gè)散列值。
此方案的代碼如下:
<?php
define ( ‘ua_seed','webapp' ) ;
session_start () ;
if ( !isset($_SESSION['user_agent'] )){
$_SESSION['user_agent'] = md5 ( $_SERVER['HTTP_USER_AGENT'].ua_seed );
}else{
if ($_SESSION['user_agent'] != md5($_SERVER['HTTP_USER_AGENT'].ua_seed)){} }
?>
通過給攻擊者制造一些麻煩,使攻擊者即使獲取了會話ID,也無法進(jìn)行破壞,能夠減少對系統(tǒng)造成的損失。
主要的安全措施有以下兩個(gè)方面。
1、防止攻擊者獲取用戶的會話ID。
獲取會話ID的方式很多,攻擊者可以通過查看明文通信來獲取,所以把會話ID放在URL中或者放在通過未加密連接傳輸?shù)腃ookie中是很危險(xiǎn)的;還有在URL中(作為_get()參數(shù))傳遞會話ID也是不安全的,因?yàn)闉g覽器歷史緩存中會存儲URL,這樣就很容易被讀取。(可以考慮使用ssh進(jìn)行加密傳輸)
還有一種更為隱蔽的攻擊手段,攻擊者通過一個(gè)被腳本攻擊突破的Web站點(diǎn),把被突破的這個(gè)站點(diǎn)上的用戶重新定向到另一個(gè)站點(diǎn),然后在重新定向的站點(diǎn)的URL中插入以下代碼:
?PHPSESSID=213456465412312365465412312;
最后發(fā)送到Web應(yīng)用程序。當(dāng)用戶查看Web應(yīng)用程序時(shí),PHP會發(fā)現(xiàn)沒有與這個(gè)會話ID相關(guān)聯(lián)的數(shù)據(jù)并且會創(chuàng)建一些數(shù)據(jù)。用戶不知道發(fā)生了什么,但攻擊者卻知道了會話ID,就可以利用這個(gè)會話ID進(jìn)入應(yīng)用程序。
要防止這種攻擊,有兩種方法。
(1)檢查php.ini中是否打開了session.use_only_cookie。如果是這種情況,PHP會拒絕基于URL的會話ID。
(2)當(dāng)啟動會話時(shí),在會話數(shù)據(jù)中放一個(gè)變量,這個(gè)變量表示會話是用戶創(chuàng)建的;如果發(fā)現(xiàn)會話數(shù)據(jù)中沒有這個(gè)變量,那就說明會話ID是假的,就可以調(diào)用session_regenerate_id函數(shù),給現(xiàn)有會話分配一個(gè)新的會話ID。
示例:
通過判斷變量是否存在來確定會話ID的真假,如果存在,則說明會話ID是真的,否則是假的,并使用session_regenerate_id()函數(shù)對會話ID進(jìn)行更改,重新給會話創(chuàng)建一個(gè)新的會話ID,
代碼如下:
復(fù)制代碼 代碼如下:
< ?php
session_start () ;
if (!isset ( $_SESSION['shili1'] )) { //判斷shili1變量是否配置
$old_id = session_id () ; //原來的會話ID的變量名
session_regenerate_id () ; //獲取一個(gè)新的會話ID
$new_id = session_id () ; //新的會話ID的變量名
echo "old : $old_id<br/>" ; //輸出原來的會話ID
echo "new : $new_id<br/>" ; //輸出新的會話ID
$_SESSION['shili1'] = TRUE ; }
?>
運(yùn)行結(jié)果如圖所示:

這只是一個(gè)示例,輸出會話ID是為了更好的理解和應(yīng)用這個(gè)函數(shù),而在程序設(shè)計(jì)中是不需要輸出會話ID的。
2、限制攻擊者獲取會話ID。
限制攻擊者獲取會話ID的方法如下。
(1)使用一個(gè)函數(shù)(md5)計(jì)算User-Agent頭加上某些附加字符串?dāng)?shù)據(jù)后的散列值(hash)。(散列函數(shù)(hash function)接受一個(gè)任意大的數(shù)據(jù)集,并且將它轉(zhuǎn)換為一個(gè)看起來完全不同的數(shù)據(jù),這個(gè)數(shù)據(jù)很短。產(chǎn)生的散列值是完全不可重現(xiàn)的,也不可能由另一個(gè)輸入產(chǎn)生。)
在User-Agent字符串后面添加一些數(shù)據(jù),攻擊者就無法通過對常見的代理值計(jì)算md5編碼來試探User-Agent字符串。
(2)將這個(gè)經(jīng)過編碼的字符串保存在用戶的會話數(shù)據(jù)中。
(3)每次從這個(gè)用戶接收到請求時(shí),檢查這個(gè)散列值。
此方案的代碼如下:
復(fù)制代碼 代碼如下:
<?php
define ( ‘ua_seed','webapp' ) ;
session_start () ;
if ( !isset($_SESSION['user_agent'] )){
$_SESSION['user_agent'] = md5 ( $_SERVER['HTTP_USER_AGENT'].ua_seed );
}else{
if ($_SESSION['user_agent'] != md5($_SERVER['HTTP_USER_AGENT'].ua_seed)){} }
?>
通過給攻擊者制造一些麻煩,使攻擊者即使獲取了會話ID,也無法進(jìn)行破壞,能夠減少對系統(tǒng)造成的損失。
您可能感興趣的文章:
- php通過會話控制實(shí)現(xiàn)身份驗(yàn)證實(shí)例
- PHP入門教程之會話控制技巧(cookie與session)
- PHP會話控制:Session與Cookie詳解
- php中session_id()函數(shù)詳細(xì)介紹,會話id生成過程及session id長度
- 比較全的PHP 會話(session 時(shí)間設(shè)定)使用入門代碼
- 使用PHP會話(Session)實(shí)現(xiàn)用戶登陸功能
- php簡單的會話類代碼
- php使用Cookie實(shí)現(xiàn)和用戶會話的方法
- php實(shí)現(xiàn)session自定義會話處理器的方法
- PHP會話控制實(shí)例分析
相關(guān)文章
Ajax+Jpgraph實(shí)現(xiàn)的動態(tài)折線圖功能示例
這篇文章主要介紹了Ajax+Jpgraph實(shí)現(xiàn)的動態(tài)折線圖功能,結(jié)合實(shí)例形式分析了ajax結(jié)合jpgraph.php類庫繪制動態(tài)折線圖的相關(guān)操作技巧,需要的朋友可以參考下2019-02-02解決文件名解壓后亂碼的問題 將文件名進(jìn)行轉(zhuǎn)碼的代碼
中文win32下,文件名使用GBK編碼 Linux下,文件名使用UTF-8編碼 解決文件名解壓后亂碼的問題,使用將文件名進(jìn)行轉(zhuǎn)碼2012-01-01

PHP用SAX解析XML的實(shí)現(xiàn)代碼與問題分析
近日在做一個(gè)解析XML的小程序,因?yàn)榉?wù)器是PHP4的,XML解析函數(shù)只能用SAX方式的xml_parser來解析了。
2011-08-08