簡體   English   中英

使用php中的會話防止登錄攻擊

[英]Prevent attack on login using sessions in php

我正在嘗試使用會話來存儲登錄嘗試的數量。 當達到最大登錄嘗試次數時,我將客戶端的IP地址存儲在黑名單表中。

我考慮過的一些事情,您可能需要了解:

  • 我正在使用session_regenerate_id(); 在我設置會話值之后。
  • 我不會在會話之外使用任何cookie,因為這不是必需的,而不是2012:p
  • 用戶IP被列入黑名單,直到我從黑名單表中刪除他的行。
  • SESSION_MAX_ATTEMPTS是已定義的常量,設置為5。
  • index.php?module=login&task=blacklist page只是向用戶顯示一條被列入黑名單的消息。 此頁面沒有任何功能。
  • 我正在使用自定義構建php框架,所以我不得不將一些名為method的OOP轉換為簡化的php代碼。

在執行登錄查詢之前調用以下函數:

private function preventAttack()
{
    $blocked = getData("SELECT count(*) as blocked FROM blacklist WHERE ip = @Value0;", Array( $_SERVER['REMOTE_ADDR'] ));
    if($blocked[0]["blocked"] == "1")
    {
        redirect("index.php?module=login&task=blacklist");
    }
    $old = (int)$this->session->get("login_attempts");
    if(!empty($old))
    {           
        if($old > SESSION_MAX_ATTEMPTS)
        {
            setData("INSERT INTO blacklist SET ip = @Value0;", Array( $_SERVER['REMOTE_ADDR'] ));
            redirect("index.php?module=login&task=blacklist");
        }
        else
        {
            $old++;
            $this->session->set("login_attempts",$old);
        }
    }
    else
    {
        $this->session->set("login_attempts", 0);
    }
}

第一個if語句的工作原理包括兩個查詢,但我堅持認為存儲嘗試次數的最佳方法是什么,以及最好的方法是什么? 也許你們可以讓我朝着正確的方向前進。

如果您對我的代碼有任何疑問,請添加評論。 我知道它有點不可讀,因為它來自我的框架,我在發布之前已經翻譯了一下。

存儲數據庫中失敗嘗試的次數,而不是會話。 注意:您可能需要將每個失敗以及時間戳保留在其自己的記錄中(並忽略/刪除任何早於閾值的內容)。

順便說一句,回應deceze的評論:

這種方法存在巨大缺陷:會話取決於客戶端發送cookie。 真正的攻擊者根本不會發回cookie。 ziiiing你必須通過IP來獲取一切。

對此的解決方案是,您不接受未在其他地方設置的有效會話cookie附帶的登錄嘗試。

非常感謝,我從你的評論中學到了很多東西。 對於有相同問題的用戶,我將解釋我所學到的知識以及我如何使用這些知識。

到目前為止我學到了什么:

  1. 真正的攻擊者根本不會發回cookie。 因此,在這種情況下使用cookie或會話沒有任何意義。
  2. 如果要將攻擊者列入黑名單,請使用可以自動為您執行此操作的防火牆。 從您的腳本執行此操作是沒有意義的,會話太容易被規避,如果您檢查IP地址,您可能會阻止整個辦公室或學校使用相同的外部IP。
  3. 無論您做什么:僅將登錄嘗試數據存儲在數據庫/ flatfile / etc中的服務器上。 用戶或攻擊者將無法輕松編輯此數據。
  4. 如果您確實在Web服務器上存儲數據以提高性能,請將其存儲在文件中,而不是數據庫中。

如果我忘記了什么請評論,我將編輯這篇文章。

我檢查了我的托管服務提供商,他們已經使用上面提到的防火牆之類的解決方案阻止了很多這些攻擊者。 所以我將停止嘗試在我的腳本中執行此操作。

我的腳本現在已修復,只有黑名單用戶和noob黑客猜測密碼:

private function preventAttack()
{
    $blocked = getData("SELECT count(*) as blocked FROM blacklist WHERE ip = @Value0;", Array( $_SERVER['REMOTE_ADDR'] ));
    if($blocked[0]["blocked"] == "1")
    {
        redirect("index.php?module=login&task=blacklist");
    }
    $old = (int)$this->session->get("login_attempts");
    if($old > 0)
    {           
        if(($old + 1) >= SESSION_MAX_ATTEMPTS)
        {
            setData("INSERT INTO blacklist SET ip = @Value0;", Array( $_SERVER['REMOTE_ADDR'] ));
            $this->session->set("login_attempts", 0);
            redirect("index.php?module=login&task=blacklist");
        }
        else
        {
            $old++;
            $this->session->set("login_attempts",$old);
        }
    }
    else
    {
        $this->session->set("login_attempts", 1);
    }
}

由於我不太確定這個平台將獲得多少用戶,並且我不希望可能的高mysql服務器負載我決定不在數據庫中存儲登錄嘗試。 也許在未來,誰知道。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM