首頁  >  文章  >  後端開發  >  使用php 中的session安全嗎?

使用php 中的session安全嗎?

怪我咯
怪我咯原創
2017-07-05 09:44:491437瀏覽

PHP中的session安全性嗎? PHP只是為我們提供了一個session的實現,後續的安全工作需要程式設計師自己靈活去掌握,所以說PHP程式真的很靈活,需要了解PHP中session安全的朋友可以參考一下

做PHP開發這麼長時間,還真沒有真正關注過安全的問題,每次都是以完成專案為主,最近在網路上看到了一篇關於安全的文章,看完以後才注意到自己以前的專案都存在著很大的安全漏洞,於是挑了一個專案進行了測試,發現很容易就中招兒了。在這裡我會分享自己寫的一個測試的例子來說明PHP中的session是如何不安全的,以及在專案中如何加強其安全性。
對於session的原理機制,網路上有很多好的文章要介紹,我們可以自行查閱。下面直接分享測試用的例子。
這個測試的​​例子主要就是一個登入頁,登入成功以後可以修改密碼,就這樣一個簡單的功能。
介面如下

首先是在專案入口的地方使用函數 session_start() 開啟了session。這樣當客戶端發起請求的時候,會產生一個身分識別 也就是 SessionID。透過cookie的方式保存在客戶端,客戶端和服務端每次的通訊都是靠這個SessionID來進行識別的。
登入成功以後,會將 使用者id、使用者名稱存入session中

$_SESSION[‘userid'] = 用户id
$_SESSION[‘uname'] = 用户名

以後所有的操作都是透過判斷 $_SESSION[‘userid']是否存在來檢查使用者是否登入。程式碼如下:

if(isset($_SESSION['userid'])) return true;

對於修改密碼介面的呼叫是透過ajax  post的方式將資料傳送到服務端的。

$.post("接口*******",
  {
     oldpass:oldpass,
     newpass:newpass,
     userid:uid,
  },
  function(data){
     data = eval('(' +data+ ')');
     $('.grant_info').html(infos[data.info]).show();
  }
);

注意,我這裡將這段程式碼寫在了html頁面中,所以說如果看到了html程式碼,也就知道了介面位址了。
修改密碼的介面是這樣實現的,首先是判斷使用者是否登錄,如果登入才會進行密碼的修改操作。
測試例子的實作思維大概就是上面介紹的那樣。
利用SessionID攻擊
1. 首先是獲取SessionID,當然攻擊者獲取此標識的方式有很多,由於我的水平有限,至於如何獲取我在這裡不做介紹。我們可以模擬一下,先正常存取此項目,然後透過瀏覽器查看SessionID,以得到一個合法的使用者識別。可以在請求頭中看到此項目ID

 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Connection: keep-alive
Cookie: Hm_lvt_bf1154ec41057869fceed66e9b3af5e7=1450428827,1450678226,1450851291,1450851486; PHPSESSID=2eiq9hcpu3ksri4r587ckt9jt7;
Host: ******
Referer: ******
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:41.0) Gecko/20100101 Firefox/41.0

得到sessionID以後,如果此用戶登入成功,那麼服務端的session裡就有此用戶的資訊了。
2. 取得到SessionID以後,如果攻擊者已經知道修改密碼的接口,就可以直接修改此使用者的密碼了。如果攻擊者還沒有得到介面位址,可以透過查看頁面代碼找出介面位址。可以使用如下的命令

#curl --cookie "PHPSESSID=2eiq9hcpu3ksri4r587ckt9jt7" 页面地址

上面我們說過,在此範例中ajax程式碼是寫在html頁面中的,所以在此頁面可以查看到介面位址
部分html程式碼如下

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
……
var uid = $(".userid").val();
$.post("/User/User/modifypass_do",
     {
        oldpass:oldpass,
        newpass:newpass,
        userid:uid,
     },
    function(data){
      data = eval(&#39;(&#39; +data+ &#39;)&#39;);
      $(&#39;.grant_info&#39;).html(infos[data.info]).show();
    }
 );
……
<span><input type="password" name="oldpass" id="textfield_o" placeholder="原密码"></span>
<span><input type="password" name="newpass" id="textfield_n" placeholder="新密码"></span>
<span><input type="password" name="confirmpass" id="textfield_c" placeholder="确认密码"></span>
<input type="button" class="btn_ok" value="确认修改" />

3. 得到介面以後可以透過curl 模擬post發送資料來修改密碼
指令如下

# curl --cookie "PHPSESSID=2eiq9hcpu3ksri4r587ckt9jt7" -d oldpass=111111 -d newpass=000000 -d userid=用户id 接口地址

如果此使用者已經登錄,那麼攻擊者可以透過執行以上指令修改使用者的密碼。
解決方法
對於上述方式的攻擊,我們可以透過使驗證方式複雜化來加強其安全性。其中一個方式就是利用請求頭中的User-Agent項來加強其安全性

 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Connection: keep-alive
Cookie: Hm_lvt_bf1154ec41057869fceed66e9b3af5e7=1450428827,1450678226,1450851291,1450851486; PHPSESSID=2eiq9hcpu3ksri4r587ckt9jt7;
Host: ******
Referer: ******
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:41.0) Gecko/20100101 Firefox/41.0

在專案開始的時候最初我們只是用了session_start()函數來開啟session。現在我們可以在session_start() 下面 新增這段程式碼

$_SESSION[‘User_Agent&#39;] = md5($_SERVER[‘HTTP_USER_AGENT&#39;]);

然後在每次判斷是否登入的時候,加入判斷條件如下

If(isset($_SESSION[‘userid&#39;]) && $_SESSION[‘User_Agent&#39;] == md5($_SERVER[‘HTTP_USER_AGENT&#39;])){
    return true;
}

這樣就可以避免上述簡單的攻擊。
總結:
當然,實際情況中的攻擊遠非這麼簡單,首先在獲取SessionID這一步就比較困難,然後就是和服務端交互的代碼盡量加密,可以避免上述的情況。在我們第二次修改程式碼以後,可以增加攻擊的複雜程度,並不能杜絕攻擊。攻擊的方式多種多樣,這裡只是一種簡單的方式,僅提供一種思路,但是原理是一樣的,在實際情況中可以根據實際情況增強我們程式碼的安全程度。

這裡只是分享自己在工作上碰到的問題,權當拋磚引玉,希望大家可以進一步深入學習。

以上是使用php 中的session安全嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn