Old code:
This is an update on the code and suggestions I received from generous users on the old thread.
So same rules apply, just check it out, tell me what you think. Is it better or worse? is the security getting better and if so what else can I do to make it better? Are the sessions correctly called/executed? Is the password check/storage correct?
script: ../includes/access.inc.php
<?php
session_start(); //start session
//password hash library
require $_SERVER['DOCUMENT_ROOT'] . '/includes/password_compact/lib/password.php';
$GLOBALS["isAdmin"] = FALSE; //default set not to admin
//set the session time
if (!isset($_SESSION['mintime'])) {
$_SESSION['mintime'] = array( 0, time() );
}
function userIsLoggedIn()
{
//if the user clicked the logout button
if (isset($_POST['action']) and $_POST['action'] == 'logout') {
echo " logout has been clicked. ";
unsetSessions(); //return false and clear sessions variables
}
//if the user hit the admin view button
if (isset($_POST['action']) and $_POST['action'] == 'admin') {
header('Location: ' . $_POST['gotoadmin']);
exit();
}
//if you are still logged in check the session
if (isset($_SESSION['loggedIn']) and (!empty($_SESSION['user'])) ) {
return checkSessionID($_SESSION['user']);
}
//if post is not set, and if not set action post or the action post is not equal to login
if (!isset($_POST) and (!isset($_POST['action']) or $_POST['action'] != 'login')) {
return FALSE;
}
//if the username post or the password post is empty
if (empty($_POST['user']) or empty($_POST['password'])) {
return FALSE;
}
array_push($_SESSION['mintime'], time()); // Push session element onto the end of the time array
array_shift($_SESSION['mintime']); // Shift the session element off the beginning of the time array
// minimum time (in seconds) between valid form submissions
if ($_SESSION['mintime'][1] - $_SESSION['mintime'][0] < 2) {
return FALSE;
}
$username = test_input($_POST['user']); //grab the username post and test the input
// are you logging into the admin page or the forum page? cause login.html script is used for both.
if ($GLOBALS['adminPage'] == 1 and $username != 'admin') {
return FALSE;
}
$passtemp = test_input($_POST['password']); //grab the password post and test the input
//this session variable determines which PDO connect script to use to log into the database,
// as admin with admin privilages or as standard privilage.
if ($username == 'admin') {
$GLOBALS["isAdmin"] = TRUE;
}
if (!databaseContainsUser($username, $passtemp)) { //if you are not in the database/wrong password
unsetSessions();
return FALSE;
} //failed the credentials screen
if (!isset($_SESSION['session_id'])) { //if you have never logged in here before...
updateSessionID($username); //update your with a query to post a new UUID() in the sessID users column
setSessionID($username); // select that newly created UUID()) from database and place it into session variable['session_id']
//set sessions variables (loggedIn, user, pass) the returns true here and exits here once complete.
setSessions($username, $passtemp);
}
//if you have been here before but your session variable does not
//match the one in the database then clear the sessions variables return false
if ( isset($_SESSION['session_id']) and !checkSessionID($username) ) {
echo "session_id keys do not match.";
unsetSessions();
}
//If your credentials are good, and you already have a set Session ID and they match up then do this...
updateSessionID($username); //update the old sessID to a new UUID()
setSessionID($username); //set the new session_id variable to the new one
//setSessions($username, $passtemp);//this could be where the double is coming from
return TRUE;
} //end function
function databaseContainsUser($username, $passtemp)
{
//I feel as if this could be a potential security issue, how else can i do this?
if ($GLOBALS["isAdmin"] == TRUE) {
include 'adminconnect.php';
}
include 'connect.php';
try {
$sql = "select count(*) from users where username = :user";
$s = $pdo->prepare($sql);
$s->bindValue(':user', $username);
$s->execute();
}
catch (PDOException $e) {
echo "Error" . $e->getMessage();
}
$count = $s->fetch();
if (!$count[0] > 0) {
return FALSE; //failed
}
if (!isPasswordGood($username, $passtemp)) {
return FALSE; //failed
}
return TRUE;
} //end function
function isPasswordGood($username, $passtemp)
{
include 'connect.php';
//query hash password in database
try {
$sql = "SELECT password FROM `users` WHERE username = :user";
$s = $pdo->prepare($sql);
$s->bindValue(':user', $username);
$s->execute();
}
catch (PDOException $e) {
echo "Error" . $e->getMessage();
}
$row = $s->fetch(); //grab hash array
$hash = array_slice($row, 0, 3); //break up the array
if (password_verify($passtemp, $hash[0])) { //call password_verify() on hash
return TRUE; //password is good
} else {
return FALSE; //bad
}
} //end isPasswordGood()
//validate input
function test_input($data)
{
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
return $data;
}
//set session variables here
function setSessions($username, $passtemp)
{
$_SESSION['loggedIn'] = TRUE;
$_SESSION['user'] = $username;
return TRUE;
}
//unset session variables here
function unsetSessions()
{
unset($_SESSION['session_id']);
unset($_SESSION['loggedIn']);
unset($_SESSION['user']);
return FALSE;
}
//this function sets the session ID
function setSessionID($username).........etc......etc.......
script: reguser.html.php
//^other code above/below
function inputData($username, $password, $email)
{
include $_SERVER['DOCUMENT_ROOT'] . '/includes/connect.php';
try {
$sql = "insert into users (username, password, email, reg_date) values (:username, :password, :email, CURDATE())";
$s = $pdo->prepare($sql);
$s->bindValue(':username', $username);
$s->bindValue(':password', $password);
$s->bindValue(':email', $email);
$s->execute();
return TRUE;
}
catch (PDOException $e) {
echo "Error" . $e->getMessage();
return FALSE;
}
} //end function