2011-07-29 137 views
1

我正在登錄表單,我必須限制嘗試3,然後阻止任何形式提交10分鐘。以下代碼無法正常工作,我需要知道如何在嘗試失敗後阻止提交。謝謝。安全PHP登錄嘗試功能

function autoDefender($attempts,$username,$pass) 
    { 
    $logins=0; 
    $logins++; 
    $ats = $attempts-$logins; 
     if (isset($_POST['password']) && isset($_POST['userName'])) 
     { 
      if($_POST['password']!=$pass && $_POST['userName']!=$username) 
       { 
        if($logins == $attempts) 
         { 
         echo ("<div class='errmg'>Acess denied for 1 minute</div>"); 
         } 
        echo ("<div class='errmg'>Error: 
        invalid username or pass; <span class='atmpts'>$ats</span> attempts left</div>"); 
       } 
     } 
    } 
+0

如何使用存儲的值創建cookie,並設置爲在10分鐘後過期。 –

+1

這是一個很好的問題!但是你首先說'logins = 0',然後'logins ++',你也可以說:'logins = 1'。因爲你將它設置爲0,然後增加它。所以它將永遠是1 :) – Milaan

+2

您必須將登錄嘗試保存在某個地方,例如在數據庫中。對於每次新嘗試,您都會+1,直到達到限制,然後節省時間並讓用戶等待。 – ComFreek

回答

4

這裏的問題是,每次調用autoDefender時,局部變量$logins被重置爲0。因此,在多次調用autoDefender時,實際發生多少次嘗試的狀態不會被維護。

您需要將此信息永久存儲在某個位置。在你的情況下,甚至跨多個請求。

請注意,這也會對拒絕服務攻擊構成攻擊面,因爲您可以鎖定其他用戶。所以你應該三思而後行。如果每個用戶都這樣做,攻擊者可能會在對所有用戶進行批量攻擊時鎖定多個用戶。如果您按照遠程客戶端(例如IP地址)執行此操作,則可能會鎖定恰好使用相同系統(例如公司或大學網絡)的其他無辜用戶。如果每個會話都這樣做,攻擊者可能會放棄發佈的會話ID。

1

因爲你的代碼每次執行從一開始,所以每次登錄$ 0。因此,你需要用0無法初始化您的變量初始化,但是從以前的登錄嘗試的次數的值從這個ip(它應該存儲在某個地方,即在數據庫上)。

不要聽取建議以在cookie(或sesstion)上存儲$登錄。它可以(而且會)被攻擊者簡單地抹去。相反,將它存儲在服務器端的某個地方:sql數據庫,memcached,berkley數據庫......有很多選項。

最後,對我來說,你似乎誤解了基本的(web,也許不僅僅是web)編程概念,所以最好從你的導師那裏仔細檢查你的代碼或者使用來自stackexchange網絡的代碼評論網站。特別是在編寫如此重要的安全相關代碼時。

+0

xml或json在哪裏? XML和json只是一種格式,而不是數據庫或存儲引擎。如果您正在討論從文本文件讀取和傾倒文件,您需要自己關注併發性問題,而簡單快速的berkleydb則爲您提供幫助。 – rvs

+0

我知道$ logins初始化爲0.我寫這個是因爲有人可以告訴如何初始化變量並正確地增加它,而不是因爲我不知道什麼是編程概念。 – George

+0

因此,您需要初始化您的變量不是0,而是從此ip的先前登錄嘗試次數的值中進行初始化。 – rvs