I am building a login script with a brute force checker that, when triggered, displays reCAPTCHA. The problem that I am having is that when the correct username/password/captcha response are entered, the login script runs but not until the majority of the page content has loaded (this happens after the form is submitted). The result is that I must hit F5 to refresh the page and resubmit the form data in order for the session to be active when the page begins to load.
Now, the problem that I am having is that, once the form is submitted (when it requires a CAPTCHA that is), the session is not started until index.php gets to
else {
$captchaResponse = 1;
$auth = Auth::verifyPass($userName,$password,$captchaResponse);
}
I am stumped as to how I can reorganize this so that the session is started way before that. Any ideas?
The first part is the index.php page containing the code that is triggered if a brute force attempt is detected. This portion of the code begins with the conditional if($auth === "bruteForce") This code displays reCAPTCHA and is supposed to submit the username, password and reCAPTCHA response code (0-incorrect response, 1-correct response) back to the login function.
<?php
include('includes/header.php');
spl_autoload_register(function ($class){
include 'includes/class.' . $class . '.php';
});
if(null !==(filter_input(INPUT_POST,'userName'))){$userName = filter_input(INPUT_POST,'userName');}
if(null !==(filter_input(INPUT_POST,'password'))){$password = filter_input(INPUT_POST,'password');}
if(isset($userName)&& isset($password)){
$auth = Auth::verifyPass($userName,$password);
}
if(isset($_GET['logout']) && $_GET['logout'] == true){
session_start();
session_destroy();
setcookie ("PHPSESSID", "", time() - 3600, "/");
header("Location: index.php");
}
if(Auth::checkLoggedIn() === true){
if(session_id() !== ''){echo 'Session ID is not blank<br />';}
echo '<a href="index.php?logout=true">Logout</a><br />';
echo 'Welcome! This is protected content!' . "<br />";
}
if(!Auth::checkLoggedIn()) :
?>
<h1>Sign In</h1>
<?php if(isset($userName) && isset($password)){if($auth === "invalidPassword"){echo '<span class="error">Invalid username or password</span>';}} ?>
<form name="login" method="post" action="index.php" id="loginForm">
<ul>
<li>
<input placeholder="Username" type="text" name="userName" id="userName" class="login" />
</li>
<li>
<input placeholder="Password" type="password" name="password" id="password" class="login" />
</li>
<?php
if(isset($userName) && isset($password)){
echo $auth . "<br />";
if($auth === "bruteForce"){
echo $auth;
require_once('includes/recaptchalib.php');
// Get a key from https://www.google.com/recaptcha/admin/create
$publickey = "xxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$privatekey = "xxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$resp = null;
$error = null;
if(isset($_POST["recaptcha_response_field"])){
$resp = recaptcha_check_answer ($privatekey,
$_SERVER["REMOTE_ADDR"],
$_POST["recaptcha_challenge_field"],
$_POST["recaptcha_response_field"]);
if ($resp->is_valid) {
Auth::checkLoggedIn();
$auth = Auth::verifyPass($userName,$password,1);
} else {
$auth = Auth::verifyPass($userName,$password,0);
//$captchaResponse = 2;
}
}
echo recaptcha_get_html($publickey, $error);
if($auth === "invalidCaptcha"){
echo "Invalid Captcha Response. Please try again.";
}
}
}
if(isset($auth)){echo $auth;}
?>
<div class="clearAll"> </div>
<li id="submit">
<input type="submit" value="Login" id="loginBtn" class="login" />
</li>
<li id="reset">
<input type="reset" value="Reset" id="resetBtn" class="login" />
</li>
</ul>
</form>
<div class="clearAll"> </div>
<h1>New User?</h1>
<p><a href="register.php">Sign Up!</a></p>
<?php endif; ?>
<div class="clearAll"> </div>
<?php include('includes/footer.php'); ?>
</body>
</html>
This is the log in function
public static function verifyPass($username,$password,$captchaResponse = 3){
$authenticatedUser = FALSE;
$bruteTest = self::_bruteTest($username);
if($bruteTest === TRUE && $captchaResponse === 3){
$status = "bruteForce";
return $status;
} else if($bruteTest === TRUE && $captchaResponse === 0){
//The brute force check was positive and the captcha response failed
//Don't even try to log in because the captcha failed.
$status = "invalidCaptcha";
return $status;
} else if ($bruteTest === TRUE && $captchaResponse === 1){
//The brute force check was positive and the captcha response was successful
//Try to log in now.
$continueLogin = TRUE;
} else if($bruteTest === FALSE){
//The bruteTest was negative, proceed with login.
$continueLogin = TRUE;
}
if($continueLogin === TRUE){
try{
$connection = Database::getDbConnection();
if($connection){
$query = "SELECT usr_name, usr_pass, usr_salt, uid, email_pri FROM users WHERE usr_name=? LIMIT 1";
$stmt = $connection->prepare($query);
$stmt->execute(array($username));
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
if($stmt->rowCount() === 0){$authenticatedUser = FALSE;} //Username was not found We are not going to say which was incorrect, only that the "username or password was incorrect"
if($results){
$resultsArray = $results[0];
$connection = null;
echo "<br />";
$dbUserName = $resultsArray['usr_name'];
$dbPass = $resultsArray['usr_pass'];
$dbSalt = $resultsArray['usr_salt'];
$dbUid = $resultsArray['uid'];
$dbEmail = $resultsArray['email_pri'];
$passHash = hash('sha512',$password);
$passToCheck = hash('sha512',$dbSalt.$passHash);
if($passToCheck != $dbPass){
$authenticatedUser = FALSE; //Password did not match. We are not going to say which was incorrect, only that the "username or password was incorrect"
} else if ($passToCheck === $dbPass && $username === $dbUserName){
$authenticatedUser = TRUE;
}
}
}else if(!$results){$authenticatedUser = FALSE;}
} catch (PDOException $e) {
echo "Error: " . $e->getMessage() . "<br />";
die();
}
try{
if($authenticatedUser === FALSE){
//Log the failed attempt into the database
$remoteIp = $_SERVER['REMOTE_ADDR'];
try {
$connection = Database::getDbConnection();
if($connection){
$query = "INSERT INTO `login_attempts`(`usr_name`, `usr_ip`) VALUES (:usr_name,INET_ATON(:usr_ip))";
$stmt = $connection->prepare($query);
$stmt->execute(array(':usr_name' => $username, ':usr_ip' => $remoteIp));
}
$connection = null;
} catch (PDOException $e){
echo "Error: " . $e->getMessage() . "<br />";
die();
}
$status = "invalidPassword";
return $status;
exit();
}else if($authenticatedUser === TRUE){
//Clear login attempts from the database
self::_clearAttempts($username);
//Start the session (if not already started somehow. session and cookie expiration need to be adjusted so that the session does not persist after browser close)
if(!isset($_SESSION)){
session_start();
}
//Set the session variables
$_SESSION['userIp'] = $_SERVER['REMOTE_ADDR'];
$_SESSION['userName'] = $dbUserName;
$_SESSION['userAgent'] = $_SERVER['HTTP_USER_AGENT'];
$session_name = 'sec_session_id';
$httponly = TRUE;
$cookieParams = session_get_cookie_params();
session_set_cookie_params($cookieParams["lifetime"],
$cookieParams["path"],
$cookieParams["domain"],
$httponly);
session_name($session_name);
}
} catch (PDOException $e) {
echo "Error: " . $e->getMessage() . "<br />";
die();
}
//End $continueLogin statement below
}
}
Move this:
if(!isset($_SESSION)){
session_start();
}
to the top of your script and try it.
or just:
session_start();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With