Add proper session management (CSRF, secure cookies, session tracking)
Co-authored-by: naielv <109038805+naielv@users.noreply.github.com>
This commit is contained in:
12
public_html/_incl/logout.php
Normal file
12
public_html/_incl/logout.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
require_once "tools.session.php";
|
||||||
|
require_once "tools.security.php";
|
||||||
|
|
||||||
|
$redir = safe_redir($_GET["redir"] ?? "/");
|
||||||
|
$cookie_options_expired = ["expires" => time() - 3600, "path" => "/", "httponly" => true, "secure" => true, "samesite" => "Lax"];
|
||||||
|
setcookie("auth_user", "", $cookie_options_expired);
|
||||||
|
setcookie("auth_pass_b64", "", $cookie_options_expired);
|
||||||
|
session_unset();
|
||||||
|
session_destroy();
|
||||||
|
header("Location: $redir");
|
||||||
|
die();
|
||||||
@@ -39,6 +39,9 @@ if (($_SESSION["auth_ok"] ?? false) != true
|
|||||||
$_SESSION["auth_user"] = $username;
|
$_SESSION["auth_user"] = $username;
|
||||||
$_SESSION["auth_data"] = db_build_auth_data($row);
|
$_SESSION["auth_data"] = db_build_auth_data($row);
|
||||||
$_SESSION["auth_ok"] = true;
|
$_SESSION["auth_ok"] = true;
|
||||||
|
if (empty($_SESSION["session_created"])) {
|
||||||
|
$_SESSION["session_created"] = time();
|
||||||
|
}
|
||||||
init_active_org($_SESSION["auth_data"]);
|
init_active_org($_SESSION["auth_data"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start([ 'cookie_lifetime' => 604800 ]);
|
ini_set("session.use_only_cookies", "1");
|
||||||
ini_set("session.use_only_cookies", "true");
|
ini_set("session.use_trans_sid", "0");
|
||||||
ini_set("session.use_trans_sid", "false");
|
session_start([
|
||||||
|
'cookie_lifetime' => 604800,
|
||||||
|
'cookie_httponly' => true,
|
||||||
|
'cookie_secure' => true,
|
||||||
|
'cookie_samesite' => 'Lax',
|
||||||
|
]);
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ if (($_GET["google_callback"] ?? "") === "1") {
|
|||||||
$_SESSION['auth_user'] = $username;
|
$_SESSION['auth_user'] = $username;
|
||||||
$_SESSION['auth_data'] = db_build_auth_data($user_row);
|
$_SESSION['auth_data'] = db_build_auth_data($user_row);
|
||||||
$_SESSION['auth_ok'] = true;
|
$_SESSION['auth_ok'] = true;
|
||||||
|
$_SESSION['session_created'] = time();
|
||||||
init_active_org($_SESSION['auth_data']);
|
init_active_org($_SESSION['auth_data']);
|
||||||
$cookie_options = ["expires" => time() + (86400 * 30), "path" => "/", "httponly" => true, "secure" => true, "samesite" => "Lax"];
|
$cookie_options = ["expires" => time() + (86400 * 30), "path" => "/", "httponly" => true, "secure" => true, "samesite" => "Lax"];
|
||||||
setcookie("auth_user", $username, $cookie_options);
|
setcookie("auth_user", $username, $cookie_options);
|
||||||
@@ -141,11 +142,13 @@ if (($_GET["logout"] ?? "") === "1") {
|
|||||||
$cookie_options_expired = ["expires" => time() - 3600, "path" => "/", "httponly" => true, "secure" => true, "samesite" => "Lax"];
|
$cookie_options_expired = ["expires" => time() - 3600, "path" => "/", "httponly" => true, "secure" => true, "samesite" => "Lax"];
|
||||||
setcookie("auth_user", "", $cookie_options_expired);
|
setcookie("auth_user", "", $cookie_options_expired);
|
||||||
setcookie("auth_pass_b64", "", $cookie_options_expired);
|
setcookie("auth_pass_b64", "", $cookie_options_expired);
|
||||||
|
session_unset();
|
||||||
session_destroy();
|
session_destroy();
|
||||||
header("Location: $redir");
|
header("Location: $redir");
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
if (($_GET["clear_session"] ?? "") === "1") {
|
if (($_GET["clear_session"] ?? "") === "1") {
|
||||||
|
session_unset();
|
||||||
session_destroy();
|
session_destroy();
|
||||||
$redir = safe_redir($_GET["redir"] ?? "/");
|
$redir = safe_redir($_GET["redir"] ?? "/");
|
||||||
header("Location: $redir");
|
header("Location: $redir");
|
||||||
@@ -154,6 +157,11 @@ if (($_GET["clear_session"] ?? "") === "1") {
|
|||||||
if (isset($_POST["user"])) {
|
if (isset($_POST["user"])) {
|
||||||
$user = trim(strtolower($_POST["user"]));
|
$user = trim(strtolower($_POST["user"]));
|
||||||
$password = $_POST["password"];
|
$password = $_POST["password"];
|
||||||
|
// Validate CSRF token
|
||||||
|
$csrf_token = $_POST["_csrf"] ?? "";
|
||||||
|
if (!$csrf_token || !isset($_SESSION["login_csrf"]) || !hash_equals($_SESSION["login_csrf"], $csrf_token)) {
|
||||||
|
$_GET["_result"] = "Token de seguridad inválido. Por favor, recarga la página e inténtalo de nuevo.";
|
||||||
|
} else {
|
||||||
$row = db_get_user($user);
|
$row = db_get_user($user);
|
||||||
if (!$row || !isset($row["password_hash"])) {
|
if (!$row || !isset($row["password_hash"])) {
|
||||||
$_GET["_result"] = "El usuario no existe.";
|
$_GET["_result"] = "El usuario no existe.";
|
||||||
@@ -162,6 +170,7 @@ if (isset($_POST["user"])) {
|
|||||||
$_SESSION['auth_user'] = $user;
|
$_SESSION['auth_user'] = $user;
|
||||||
$_SESSION['auth_data'] = db_build_auth_data($row);
|
$_SESSION['auth_data'] = db_build_auth_data($row);
|
||||||
$_SESSION['auth_ok'] = true;
|
$_SESSION['auth_ok'] = true;
|
||||||
|
$_SESSION['session_created'] = time();
|
||||||
init_active_org($_SESSION['auth_data']);
|
init_active_org($_SESSION['auth_data']);
|
||||||
$cookie_options = ["expires" => time() + (86400 * 30), "path" => "/", "httponly" => true, "secure" => true, "samesite" => "Lax"];
|
$cookie_options = ["expires" => time() + (86400 * 30), "path" => "/", "httponly" => true, "secure" => true, "samesite" => "Lax"];
|
||||||
setcookie("auth_user", $user, $cookie_options);
|
setcookie("auth_user", $user, $cookie_options);
|
||||||
@@ -172,15 +181,20 @@ if (isset($_POST["user"])) {
|
|||||||
} else {
|
} else {
|
||||||
$_GET["_result"] = "La contraseña no es correcta.";
|
$_GET["_result"] = "La contraseña no es correcta.";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (strval(db_get_config('installed')) !== '1') {
|
if (strval(db_get_config('installed')) !== '1') {
|
||||||
header("Location: /_install.php");
|
header("Location: /_install.php");
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
|
if (empty($_SESSION["login_csrf"])) {
|
||||||
|
$_SESSION["login_csrf"] = bin2hex(random_bytes(32));
|
||||||
|
}
|
||||||
require_once "_incl/pre-body.php";
|
require_once "_incl/pre-body.php";
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<form method="post" action="?redir=<?= urlencode($_GET["redir"] ?? "/") ?>">
|
<form method="post" action="?redir=<?= urlencode($_GET["redir"] ?? "/") ?>">
|
||||||
|
<input type="hidden" name="_csrf" value="<?= htmlspecialchars($_SESSION["login_csrf"]) ?>">
|
||||||
<div class="card pad" style="max-width: 500px;">
|
<div class="card pad" style="max-width: 500px;">
|
||||||
<h1 style="text-align: center;">Iniciar sesión en Axia4</h1>
|
<h1 style="text-align: center;">Iniciar sesión en Axia4</h1>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -122,6 +122,12 @@ if ($initials === '') {
|
|||||||
<div class="info-row"><span class="label">ID Sesión</span><span style="font-family:monospace;font-size:.75rem;"><?= htmlspecialchars(substr(session_id(), 0, 12)) ?>…</span></div>
|
<div class="info-row"><span class="label">ID Sesión</span><span style="font-family:monospace;font-size:.75rem;"><?= htmlspecialchars(substr(session_id(), 0, 12)) ?>…</span></div>
|
||||||
<div class="info-row"><span class="label">Org. activa</span><span><?= htmlspecialchars($activeOrganization ?: '–') ?></span></div>
|
<div class="info-row"><span class="label">Org. activa</span><span><?= htmlspecialchars($activeOrganization ?: '–') ?></span></div>
|
||||||
<div class="info-row"><span class="label">Autenticación</span><span><?= empty($authData['google_auth']) ? 'Contraseña' : 'Google' ?></span></div>
|
<div class="info-row"><span class="label">Autenticación</span><span><?= empty($authData['google_auth']) ? 'Contraseña' : 'Google' ?></span></div>
|
||||||
|
<?php if (!empty($_SESSION['session_created'])): ?>
|
||||||
|
<div class="info-row"><span class="label">Sesión iniciada</span><span><?= htmlspecialchars(date('d/m/Y H:i', $_SESSION['session_created'])) ?></span></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if (!empty($_SESSION['last_reload_time'])): ?>
|
||||||
|
<div class="info-row"><span class="label">Última actividad</span><span><?= htmlspecialchars(date('d/m/Y H:i', $_SESSION['last_reload_time'])) ?></span></div>
|
||||||
|
<?php endif; ?>
|
||||||
<div style="margin-top:16px;">
|
<div style="margin-top:16px;">
|
||||||
<a href="/_incl/logout.php" class="btn btn-danger btn-sm">Cerrar sesión</a>
|
<a href="/_incl/logout.php" class="btn btn-danger btn-sm">Cerrar sesión</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user