I think I need to improve my site security where I have bunch of ajax requests.
Until now I used SESSION variables to log-in a user. Example of my login page:
login.php
/// START SECURE SESSION
function startSession($lifetime, $path, $domain, $secure, $httpOnly)
{
session_set_cookie_params($lifetime, $path, $domain, $secure, $httpOnly);
session_start();
}
// Initialize the session
if (!isset($_SESSION)) {
startSession(0, '/', 'example.com', true, true);
}
// Check if the user is already logged in
if (isset($_SESSION["loggedin"]) && $_SESSION["loggedin"] == true || !empty($_SESSION["username"])) {
header("location: https://example.com/admin/");
exit;
}
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Check if username is empty
if (empty(trim($_POST["username"]))) {
$username_err = "Username field is empty.";
} else {
$username = trim($_POST["username"]);
}
// Check if password is empty
if (empty(trim($_POST["password"]))) {
$password_err = "Password field is empty.";
} else {
$password = trim($_POST["password"]);
}
if (empty($username_err) && empty($password_err)) {
// Prepare a select statement
$sql = "SELECT id, username, password FROM login WHERE username = :username";
if ($stmt = $pdo->prepare($sql)) {
$stmt->bindParam(":username", $param_username, PDO::PARAM_STR);
// Set parameters
$param_username = trim($_POST["username"]);
// Attempt to execute the prepared statement
if ($stmt->execute()) {
// Check if username exists, if yes then verify password
if ($stmt->rowCount() == 1) {
if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$id = $row["id"];
$username = $row["username"];
$hashed_password = $row["password"];
$options = ['cost' => 12];
if (password_verify($password, $hashed_password)) {
// Password is correct, so start a new session
if (!isset($_SESSION)) {
startSession(0, '/', 'example.com', true, true);
}
// Check if the hash needs to be created again.
if (password_needs_rehash($hashed_password, PASSWORD_DEFAULT, $options))
{
$hash = password_hash($password, PASSWORD_DEFAULT, $options);
/* Update the password hash on the database. */
$query = 'UPDATE login SET password = :passwd WHERE id = :id';
$values = [':passwd' => $hash, ':id' => $id];
try
{
$res = $pdo->prepare($query);
$res->execute($values);
}
catch (PDOException $e)
{
/* Query error. */
echo 'Query error.';
die();
}
}
// Store data in session variables
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["username"] = $username;
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp
$_SESSION["twofactory"] = false;
// Redirect user to welcome page
session_regenerate_id(true);
$url = $_POST["url"];
if (!empty($url)) {
header("location: https://example.com/" . $url);
} else {
header("location: https://example.com/admin/index.php");
}
} else {
// Password is not valid, display a generic error message
$login_err = "Wrong name or password.";
//error_log("Wrong pass/username " . $ipadress . " URL: " . $actual_link, 0);
}
}
} else {
// Username doesn't exist, display a generic error message
$login_err = "Wrong name or password.";
error_log("Wrong pass/username! IP: " . $ipadress . " URL: " . $actual_link, 0);
}
} else {
echo "Error occured try again later.";
}
// Close statement
unset($stmt);
}
}
That’s how user can log-in to admin.
And in all other files (what I want to secure) I included (to top of the file) a sessioncheck.php named file and check out if the SESSION is set or not.
sessioncheck.php
if (!isset($_SESSION))
{
session_set_cookie_params(0, '/', 'example.com', true, true);
session_start();
}
$url = dirname($_SERVER['PHP_SELF']);
// Check if the user is logged in, if not then redirect him to login page
if(!isset($_SESSION["loggedin"]) || $_SESSION["loggedin"] !== true || empty($_SESSION["username"])){
header("location: https://example.com/admin/config/login.php?url=".$url);
exit;
}
If the last activity more then 1800 sec
if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) {
// last request was more than 30 minutes ago
session_unset(); // unset $_SESSION variable for the run-time
session_destroy(); // destroy session data in storage
header("location: https://example.com/admin/config/login.php?url=".$url);
exit;
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp
So my question is that if I request a file with ajax which have in the top included the sessioncheck.php file then it’s enough or I need to improve something with verification (session check?) Maybe I need to POST token with ajax and verify that also?
What do you think? What I need to improve to make my site more secure?