2010-11-12 77 views
4

方案:一個用戶已登錄足夠用戶認證的PHP會話變量?

  • 後,會話變量設置確認他們的登錄。
  • 在每頁的頂部,登錄會話變量被確認有效
  • 如果不是,它們會被引導出來。
  • 沒有永久性Cookie使用,只有session

問:

這是一個足夠強大的安全性措施是由本身,或者我應該

  • 兩個一套會話變量來驗證海誓山盟和/或
  • 執行數據庫/散列驗證
  • ...?

========

(順便說一句,當我研究這個問題,this wiki是一個夢幻般的閱讀。)

回答

6

這足以只存儲用戶登錄(或用戶id)在會話中。

爲了防止會話固定/劫持你需要的一切只是爲了實現簡單algorythm(僞):

if (!isset($_SESSION['hash']) { 
    $_SESSION['hash'] = md5(!empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'no ua'); 
} else if ($_SESSION['hash'] != md5(!empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'no ua')) { 
    session_regenerate_id(); 
    $_SESSION = array(); 
    $_SESSION['hash'] = md5(!empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'no ua'); 
} 

你可以哈希計算搬進了功能,防止重複建設,我剛一所示可能的保護草圖。

這是我如何實現這種保護在我的Kohana會話類:

abstract class Session extends Kohana_Session 
{ 
    public function read($id = null) 
    { 
     parent::read($id); 

     $hash = $this->calculateHash(); 
     $sessionHash = $this->get('session_fixation'); 

     if (!$sessionHash) { 
      $this->set('session_fixation', $hash); 
     } elseif ($sessionHash != $hash) { 
      $this->regenerate(); 
      $_SESSION = array(); 
      $this->set('session_fixation', $hash); 
     } 
    } 

    private function calculateHash() 
    { 
     $ip = !empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1'; 
     $ua = !empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'no ua'; 
     $charset = !empty($_SERVER['HTTP_ACCEPT_CHARSET']) ? $_SERVER['HTTP_ACCEPT_CHARSET'] : 'no charset'; 
     $ip = substr($ip, 0, strrpos($ip, '.') - 1); 
     return md5($ua . $ip . $charset); 
    } 
} 
+0

關於接受,但很抱歉,但我覺得我需要更多。一個或兩個參考,一些關於欺騙/劫持的論點......對我來說,在整個認證過程中只使用一個變量似乎很弱。 – Ben 2010-11-12 08:00:00

+0

劫持什麼?!會話是完全存儲在服務器上的數據。 – zerkms 2010-11-12 10:07:24

+0

@Steve:我剛剛就你的具體問題特別提出了問題:「這是否是一種足夠強大的安全措施?」。另一個鏈接到「shiflett.org」的評論有幾條**毫無意義的建議。作者有時不知道他在說什麼。 – zerkms 2010-11-12 10:12:51

2

不要嘗試寫自己的會議方案,PHP會做得更好。

是的,你可以添加更多的信息到您的$ _SESSION有助於防止會話劫持

比如我通過組合祕密短語或與用戶代理和SESSION_ID(隨機數據的指紋)和散列這一切。爲了劫持會話,用戶需要找出有效的session_id和指紋的散列。它看起來像這樣。 This is a good read

$_SESSION['fingerprint'] = md5('somethingSecret' . $_SERVER['HTTP_USER_AGENT']. session_id());

那麼你會驗證像

$check_print = md5('somethingSecret' . $_SERVER['HTTP_USER_AGENT']. session_id()); 

if($check_print != $_SESSION['fingerprint'] || $_SESSION['authenticated']){ 
    //invalid session 
} 
+0

感謝您的鏈接! – Woppi 2010-11-12 09:32:16

+0

字符串'somethingSecret'在這裏的作用是什麼,爲什麼你需要指紋中的'session_id()'? – zerkms 2010-11-12 10:09:11

+0

我建議閱讀我發佈的文章,但基本上可以讓一些惡意用戶計算出活動session_id並將其發送到服務器以嘗試訪問帳戶,他還必須提供實際上不可能的指紋哈希爲了猜測,他必須知道A)祕密字符串B)合法用戶正在使用的瀏覽器,以及C)session_id,並且必須知道使用md5散列並將其作爲會話的一部分呈現。 – Brian 2010-11-13 02:07:50

0

隨着11月15日的會議上,兩個答案我已經收到並沒有解決我的問題,這是

「是這[單個會話變量]本身是一種足夠強大的安全措施?「

This question說:是的,但似乎有一些分歧下面是各種結果的摘要:。

1)單個會話變量不夠安全因爲會話can be hijacked fairly easily

2)因爲這可能發生,所以沒有會話是真正安全的,但是通過添加指紋可以使會話更安全,這確保了每次會話需要驗證時都有唯一的可重複檢查。 User-Agent和其他一些(參考他的代碼)

3)Salting the fingerprint大部分是無用的,因爲它掩蓋了數據,但在每臺客戶端機器上都被複制,因此失去了它的獨特性。

4)數據庫解決方案是無用的,因爲它是客戶端問題。

不是我正在尋找的權威答案,但我想這將不得不做,因爲缺乏更好的東西。

閱讀已幫助/混淆我進一步:

Session hijacking and PHP

Is HTTPS the only defense against Session Hijacking in an open network?

1

沒有什麼可以做,除了使用HTTPS。

無論您添加多少cookie或散列什麼數據都無關緊要。它都可以被嗅探併發送回服務器。

如果您要強制用戶在其請求的整個生命週期中使用單個UA,可以提供以下幫助:您不需要任何特殊的哈希業務,因爲您將它散列爲$_SESSION,用戶或劫機者都不能直接訪問,那麼爲什麼還要麻煩呢?不妨在登錄時只存儲$_SESSION["reportedUA"] = $_SERVER["HTTP_USER_AGENT"],然後在每個請求中檢查reportedUA

這同樣是微不足道的劫持,一旦你意識到它的發生,因爲你只需要嗅探報道UA當你聞會話cookie,並開始使用它。

下一步是什麼? IP地址?會話劫持可能發生在NAT後面,在這種情況下,你被搞砸了。您的用戶可能會使用撥號上網,在這種情況下他們擰緊。

此問題無解:有沒辦法。沒有辦法。如果黑客能看到你的會話cookie,那麼他們可以把你弄得一團糟,因爲沒有涉及到的東西只有用戶知道(即密碼)一個與每個請求發送更多的信息或挑戰。

使會話的安全性的唯一方法是,以確保整個會話。

0

這本身就是一個足夠強大的安全措施,

一套兩枚會話變量來驗證海誓山盟和/或
實現數據庫/哈希驗證

否,原因是這樣的:如果您的有效用戶可以發送到您的服務器以進行身份​​驗證(會話ID,Cookie,某些散列字符串,任何內容!),則任何有可能被其他人嗅探到的內容都是未加密的。即使服務器使用md5散列,salt,雙會話變量檢查,id或其他方式處理數據並存儲該信息,服務器在從其他來源再次接收到欺騙數據時也可以輕鬆地進行再現。

正如很多人所建議的那樣,SSL是防止此類爆發的唯一方法。

我想到,如果服務器爲每個請求生成一個新的會話ID,並且允許瀏覽器只回復一次,那理論上在服務器和服務器之前理論上只有一個劫持者請求或帖子授權瀏覽器知道它。儘管如此,仍然令人無法接受,因爲足以造成嚴重的損失。

嘿你看這個:

創建一個單一的使用GUID和隨機鹽和使用PHP與共享的密碼進行加密 - 這是爲會話ID或Cookie發送。

客戶機接收的cookie,與使用JavaScript的共享密碼解密它(有許多可用的ENC/DEC公用事業)

設置當前cookie或會話ID到GUID。

這將確保沒有人能夠劫持會話,除非他們知道密碼,而密碼永遠不會通過網絡發送。

SSL似乎更容易,而且更安全。

編輯:好吧,它已經完成 - 沒關係;-)