Add 3 logins attempts and lock for 15 minutes

Currently looking to to add this script:
if (isset($_SESSION[‘loginCount’]))
{
$_SESSION[‘loginCount’]++;
if ($_SESSION[‘loginCount’] > 3)
{
echo ‘HACKER!’;
exit;
}
} else {
$_SESSION[‘loginCount’] = 1;
}

into my php form. But it’s doesn’t seem to work
https://pastebin.com/cVV9WPTH

Besides, what should I add to block the email for 15 minutes after the 3 failed attempts

First I just have to say there’s basically no way to stop a brute force attack and that all it does is penalize a legit users. A person who is trying to hack in a website isn’t going to be using one user account and/or computer to hack in. Anyways this is the best I could come up with :
[php]if (isset($submit) && $submit === ‘login’) {
$username = trim(filter_input(INPUT_POST, ‘username’, FILTER_SANITIZE_FULL_SPECIAL_CHARS));
$password = filter_input(INPUT_POST, ‘password’, FILTER_SANITIZE_FULL_SPECIAL_CHARS);

if (preg_match('/^[ \w]+$/', $username) && (strlen($username) > 0)) {
    $throttle_delay = throttle_failed_logins($username);
    if ($throttle_delay > 0) {
        $message = "Too many login attempts. ";
        $message .= "You must wait " . $throttle_delay . " minutes before you can attempt another login.";
    } else {
        $result = $users->read($username, $password);
        if ($result) {
            clear_failed_logins($username);
            after_successful_login();
        } else {
            record_failed_login($username);
        }
    } 
} else {
    unset($username);
}

}[/php]

here are my functions ->
[php]<?php

use Library\Database\Database as DB;

function find_username($username) {
$db = DB::getInstance();
$pdo = $db->getConnection();
$query = ‘SELECT id, username, count, last_time FROM users WHERE username=:username’;
$stmt = $pdo->prepare($query);
$stmt->execute([’:username’ => $username]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
return $result;
}

function update_failed_logins_table(array $failed_login) {
$db = DB::getInstance();
$pdo = $db->getConnection();
$query = ‘UPDATE users SET username=:username, count=:count, last_time=:last_time WHERE id=:id’;
$stmt = $pdo->prepare($query);
$stmt->execute([’:username’ => $failed_login[‘username’], ‘:count’ => $failed_login[‘count’], ‘:last_time’ => $failed_login[‘last_time’], ‘:id’ => $failed_login[‘id’]]);
}

function record_failed_login($username) {

$failed_login = find_username($username);

if (!$failed_login) {
    if (isset($_SESSION['username'])) {
        $_SESSION['count'] = $_SESSION['count'] + 1;
        $_SESSION['last_time'] = time();
    } else {
        $_SESSION['username'] = $username;
        $_SESSION['count'] = 1;
        $_SESSION['last_time'] = time();
    }
} else {
    // existing failed_login record
    $failed_login['count'] = $failed_login['count'] + 1;
    $failed_login['last_time'] = time();
    update_failed_logins_table($failed_login);
}
return true;

}

function clear_failed_logins($username) {
$failed_login = find_username($username);

if ($failed_login) {
    $failed_login['count'] = 0;
    $failed_login['last_time'] = time();
    update_failed_logins_table($failed_login);
} else {
    unset($_SESSION['username']);
    unset($_SESSION['count']);
    unset($_SESSION['last_time']);
    session_destroy();
}

return true;

}

// Returns the number of minutes to wait until logins
// are allowed again.
function throttle_failed_logins($username) {
$throttle_at = 500;
$delay_in_minutes = 5;
$delay = 60 * $delay_in_minutes;

$failed_login = find_username($username);

// Once failure count is over $throttle_at value, 
// user must wait for the $delay period to pass.
if ($failed_login && $failed_login['count'] >= $throttle_at) {
    $remaining_delay = ($failed_login['last_time'] + $delay) - time();
    $remaining_delay_in_minutes = ceil($remaining_delay / 60);
    return $remaining_delay_in_minutes;
} elseif (!$failed_login && isset($_SESSION['username']) && (int) $_SESSION['count'] > $throttle_at) {
    $remaining_delay = ($_SESSION['last_time'] + $delay) - time();
    $remaining_delay_in_minutes = ceil($remaining_delay / 60);
    return $remaining_delay_in_minutes;
} else {
    return 0;
}

}[/php]

If you notice I put my attempts at 500 basically disabling this feature for like I said it’s practically impossible stop a brute force attack. Here’s an online security scanner to validate in what I’m saying -> https://online.acunetix.com/#/dashboard/
Trust me I have tried and even research a solutions. The only thing I came up with was one reputable website basically saying don’t even bother in trying.

That is why I never try to write my own processing payment system and let the experts handle that. Whoever writes online banking applications have to really know their stuff.

You CANNOT successfully store the count or time value in session variables, since you can get a new session anytime you want by simply not propagating the session id between requests. You MUST store the count and time value on the server, i.e. in a database table.

You must also insure that failed login attempts don’t lock out an already logged in user, otherwise, someone could go through all the usernames on a site that publicly lists usernames (such as a Forum) and lock everyone out. This requires a more sophisticated log in system than just storing a user id in a session variable.

Sponsor our Newsletter | Privacy Policy | Terms of Service