Files
Axia4/public_html/_incl/tools.auth.php
copilot-swe-agent[bot] ffb6b6ce45 Security: fix auth bypass, open redirects, cookie security, OAuth CSRF, and Sf() misuse
- Fix critical inverted authentication logic in tools.auth.php (password_verify was inverted)
- Fix broken Sf() misuse for username lookups (was always returning empty string)
- Add safe_username_to_filename() to tools.security.php for proper username handling
- Fix open redirect vulnerability in _login.php for all redirect targets
- Add HttpOnly, Secure, SameSite cookie flags to all setcookie() calls
- Add CSRF nonce to OAuth state parameter and verify it on callback
- Add session_regenerate_id(true) after successful login
- Remove redundant session_regenerate_id() from tools.session.php (was called on every request)
- Add authentication check to entreaulas/_filefetch.php
- Fix broken Sf() usage in entreaulas pages (aulario.php, comedor.php, diario.php, paneldiario.php, proyectos.php, api/comedor.php)
- Fix broken Sf() usage in sysadmin/users.php and sysadmin/reset_password.php

Co-authored-by: naielv <109038805+naielv@users.noreply.github.com>
2026-02-21 18:55:06 +00:00

88 lines
3.4 KiB
PHP

<?php
require_once "tools.session.php";
require_once "tools.security.php";
if (!isset($AuthConfig)) {
$AuthConfig = json_decode(file_get_contents("/DATA/AuthConfig.json"), true);
}
$ua = $_SERVER['HTTP_USER_AGENT'];
if (str_starts_with($ua, "Axia4Auth/")) {
$username = explode("/", $ua)[1];
$userpass = explode("/", $ua)[2];
$user_filename = safe_username_to_filename($username);
if ($user_filename === "") {
header("HTTP/1.1 403 Forbidden");
die();
}
$userdata = json_decode(file_get_contents("/DATA/Usuarios/" . $user_filename . ".json"), true);
if (!$userdata) {
header("HTTP/1.1 403 Forbidden");
die();
}
if (!password_verify($userpass, $userdata["password_hash"])) {
header("HTTP/1.1 403 Forbidden");
die();
}
$_SESSION["auth_user"] = $username;
$_SESSION["auth_data"] = $userdata;
$_SESSION["auth_ok"] = true;
$_COOKIE["auth_user"] = $username;
$_COOKIE["auth_pass_b64"] = base64_encode($userpass);
$_SESSION["auth_external_lock"] = "header"; // Cannot logout because auth is done via header
}
// If $_SESSION is empty, check for cookies "auth_user" and "auth_pass_b64"
if ($_SESSION["auth_ok"] != true && isset($_COOKIE["auth_user"]) && isset($_COOKIE["auth_pass_b64"])) {
$username = $_COOKIE["auth_user"];
$userpass_b64 = $_COOKIE["auth_pass_b64"];
$userpass = base64_decode($userpass_b64);
$user_filename = safe_username_to_filename($username);
if ($user_filename !== "") {
$userdata = json_decode(file_get_contents("/DATA/Usuarios/" . $user_filename . ".json"), true);
if ($userdata && password_verify($userpass, $userdata["password_hash"])) {
$_SESSION["auth_user"] = $username;
$_SESSION["auth_data"] = $userdata;
$_SESSION["auth_ok"] = true;
}
}
}
// If session is older than 5min, reload user data
if (isset($_SESSION["auth_ok"]) && $_SESSION["auth_ok"] && isset($_SESSION["auth_user"])) {
if (isset($AuthConfig["session_load_mode"]) && $AuthConfig["session_load_mode"] === "force") {
$username = $_SESSION["auth_user"];
$user_filename = safe_username_to_filename($username);
if ($user_filename !== "") {
$userdata = json_decode(file_get_contents("/DATA/Usuarios/" . $user_filename . ".json"), true);
$_SESSION["auth_data"] = $userdata;
}
$_SESSION["last_reload_time"] = time();
} elseif (isset($AuthConfig["session_load_mode"]) && $AuthConfig["session_load_mode"] === "never") {
// Do nothing, never reload session data
} else {
if (isset($_SESSION["last_reload_time"])) {
$last_reload = $_SESSION["last_reload_time"];
if (time() - $last_reload > 300) {
$username = $_SESSION["auth_user"];
$user_filename = safe_username_to_filename($username);
if ($user_filename !== "") {
$userdata = json_decode(file_get_contents("/DATA/Usuarios/" . $user_filename . ".json"), true);
$_SESSION["auth_data"] = $userdata;
}
$_SESSION["last_reload_time"] = time();
}
} else {
$_SESSION["last_reload_time"] = time();
}
}
}
function user_is_authenticated()
{
return isset($_SESSION["auth_ok"]) && $_SESSION["auth_ok"] === true;
}
function user_has_permission($perm)
{
return in_array($perm, $_SESSION["auth_data"]["permissions"] ?? []);
}