Merge pull request #12 from Axia4/copilot/fix-security-issues
Security: fix auth bypass, open redirects, broken cookie security, OAuth CSRF, and Sf() misuse across EntreAulas
This commit is contained in:
@@ -8,12 +8,17 @@ $ua = $_SERVER['HTTP_USER_AGENT'];
|
||||
if (str_starts_with($ua, "Axia4Auth/")) {
|
||||
$username = explode("/", $ua)[1];
|
||||
$userpass = explode("/", $ua)[2];
|
||||
$userdata = json_decode(file_get_contents("/DATA/Usuarios/" . Sf($username) . ".json"), true);
|
||||
$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"])) {
|
||||
if (!password_verify($userpass, $userdata["password_hash"])) {
|
||||
header("HTTP/1.1 403 Forbidden");
|
||||
die();
|
||||
}
|
||||
@@ -30,11 +35,14 @@ if ($_SESSION["auth_ok"] != true && isset($_COOKIE["auth_user"]) && isset($_COOK
|
||||
$username = $_COOKIE["auth_user"];
|
||||
$userpass_b64 = $_COOKIE["auth_pass_b64"];
|
||||
$userpass = base64_decode($userpass_b64);
|
||||
$userdata = json_decode(file_get_contents("/DATA/Usuarios/" . Sf($username) . ".json"), true);
|
||||
if ($userdata && password_verify($userpass, $userdata["password_hash"])) {
|
||||
$_SESSION["auth_user"] = $username;
|
||||
$_SESSION["auth_data"] = $userdata;
|
||||
$_SESSION["auth_ok"] = true;
|
||||
$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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,8 +50,11 @@ if ($_SESSION["auth_ok"] != true && isset($_COOKIE["auth_user"]) && isset($_COOK
|
||||
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"];
|
||||
$userdata = json_decode(file_get_contents("/DATA/Usuarios/" . Sf($username) . ".json"), true);
|
||||
$_SESSION["auth_data"] = $userdata;
|
||||
$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
|
||||
@@ -52,8 +63,11 @@ if (isset($_SESSION["auth_ok"]) && $_SESSION["auth_ok"] && isset($_SESSION["auth
|
||||
$last_reload = $_SESSION["last_reload_time"];
|
||||
if (time() - $last_reload > 300) {
|
||||
$username = $_SESSION["auth_user"];
|
||||
$userdata = json_decode(file_get_contents("/DATA/Usuarios/" . Sf($username) . ".json"), true);
|
||||
$_SESSION["auth_data"] = $userdata;
|
||||
$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 {
|
||||
|
||||
@@ -58,6 +58,32 @@ function Si($input) {
|
||||
return $input;
|
||||
}
|
||||
|
||||
function safe_username_to_filename($username) {
|
||||
/**
|
||||
* Convert a username (plain username or email) to a safe filename for use in file operations.
|
||||
*
|
||||
* Email addresses have @ replaced with __ to match how Google OAuth users are stored.
|
||||
* The result contains only alphanumeric characters, dots, underscores, and hyphens.
|
||||
*
|
||||
* @param string $username The username or email to convert.
|
||||
* @return string The safe filename (without path or extension), or "" if invalid.
|
||||
*/
|
||||
$filename = strtolower((string)$username);
|
||||
// Remove null bytes
|
||||
$filename = str_replace("\0", "", $filename);
|
||||
// Replace @ with __ (to match Google OAuth file naming)
|
||||
$filename = str_replace("@", "__", $filename);
|
||||
// Remove any path components to prevent directory traversal
|
||||
$filename = basename($filename);
|
||||
// Remove .. sequences
|
||||
$filename = str_replace("..", "", $filename);
|
||||
// Keep only alphanumeric, dot, underscore, hyphen
|
||||
$filename = preg_replace("/[^a-zA-Z0-9._-]/", "_", $filename);
|
||||
// Trim dots and underscores from ends
|
||||
$filename = trim($filename, "._");
|
||||
return $filename;
|
||||
}
|
||||
|
||||
function Sb($input) {
|
||||
/**
|
||||
* Sanitize a boolean input by converting it to a boolean value.
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
session_start([ 'cookie_lifetime' => 604800 ]);
|
||||
session_regenerate_id();
|
||||
ini_set("session.use_only_cookies", "true");
|
||||
ini_set("session.use_trans_sid", "false");
|
||||
|
||||
@@ -5,11 +5,30 @@ if (!isset($AuthConfig)) {
|
||||
$AuthConfig = json_decode(file_get_contents("/DATA/AuthConfig.json"), true);
|
||||
}
|
||||
$DOMAIN = $_SERVER["HTTP_X_FORWARDED_HOST"] ?? $_SERVER["HTTP_HOST"];
|
||||
|
||||
/**
|
||||
* Return a safe redirect URL: only allow relative paths starting with a single slash.
|
||||
* Falls back to "/" for any external, protocol-relative, or otherwise unsafe URLs.
|
||||
*/
|
||||
function safe_redir($url) {
|
||||
$url = (string)$url;
|
||||
// Must start with a single "/" but not "//" (protocol-relative)
|
||||
if (preg_match('#^/[^/]#', $url) || $url === '/') {
|
||||
// Strip newlines to prevent header injection
|
||||
return preg_replace('/[\r\n]/', '', $url);
|
||||
}
|
||||
return '/';
|
||||
}
|
||||
|
||||
if ($_GET["reload_user"] == "1") {
|
||||
$user = str_replace("@", "__", $_SESSION["auth_user"]);
|
||||
$userdata = json_decode(file_get_contents("/DATA/Usuarios/" . Sf($user) . ".json"), true);
|
||||
$user_filename = safe_username_to_filename($_SESSION["auth_user"] ?? "");
|
||||
if ($user_filename === "") {
|
||||
header("Location: /");
|
||||
die();
|
||||
}
|
||||
$userdata = json_decode(file_get_contents("/DATA/Usuarios/" . $user_filename . ".json"), true);
|
||||
$_SESSION['auth_data'] = $userdata;
|
||||
$redir = $_GET["redir"] ?? "/";
|
||||
$redir = safe_redir($_GET["redir"] ?? "/");
|
||||
header("Location: $redir");
|
||||
die();
|
||||
}
|
||||
@@ -20,6 +39,15 @@ if ($_GET["google_callback"] == "1") {
|
||||
if (!isset($_GET["code"])) {
|
||||
die("Error: No se recibió el código de autorización de Google.");
|
||||
}
|
||||
|
||||
// Validate CSRF nonce from state parameter
|
||||
$state_raw = $_GET["state"] ?? "";
|
||||
$state = json_decode(base64_decode($state_raw), true);
|
||||
$state_nonce = $state["nonce"] ?? "";
|
||||
if (!$state_nonce || !isset($_SESSION["oauth_nonce"]) || !hash_equals($_SESSION["oauth_nonce"], $state_nonce)) {
|
||||
die("Error: Estado OAuth inválido. Por favor, inténtalo de nuevo.");
|
||||
}
|
||||
unset($_SESSION["oauth_nonce"]);
|
||||
|
||||
$code = $_GET["code"];
|
||||
|
||||
@@ -56,7 +84,11 @@ if ($_GET["google_callback"] == "1") {
|
||||
|
||||
$email = $user_info["email"];
|
||||
$name = $user_info["name"] ?? explode("@", $email)[0];
|
||||
$userfile = "/DATA/Usuarios/" . Sf(strtolower(str_replace("@", "__", $email))) . ".json";
|
||||
$user_filename = safe_username_to_filename($email);
|
||||
if ($user_filename === "") {
|
||||
die("Error: Dirección de correo inválida.");
|
||||
}
|
||||
$userfile = "/DATA/Usuarios/" . $user_filename . ".json";
|
||||
$password = bin2hex(random_bytes(16)); // Generar una contraseña aleatoria para el usuario, aunque no se usará para iniciar sesión
|
||||
if (file_exists($userfile)) {
|
||||
$userdata = json_decode(file_get_contents($userfile), true);
|
||||
@@ -72,13 +104,15 @@ if ($_GET["google_callback"] == "1") {
|
||||
file_put_contents($userfile, json_encode($userdata));
|
||||
}
|
||||
|
||||
session_regenerate_id(true);
|
||||
$_SESSION['auth_user'] = $email;
|
||||
$_SESSION['auth_data'] = $userdata;
|
||||
$_SESSION['auth_ok'] = true;
|
||||
setcookie("auth_user", $email, time() + (86400 * 30), "/");
|
||||
setcookie("auth_pass_b64", base64_encode($password), time() + (86400 * 30), "/");
|
||||
$cookie_options = ["expires" => time() + (86400 * 30), "path" => "/", "httponly" => true, "secure" => true, "samesite" => "Lax"];
|
||||
setcookie("auth_user", $email, $cookie_options);
|
||||
setcookie("auth_pass_b64", base64_encode($password), $cookie_options);
|
||||
|
||||
$redir = json_decode(base64_decode($_GET["state"]), true)["redir"] ?? "/";
|
||||
$redir = safe_redir($state["redir"] ?? "/");
|
||||
|
||||
header("Location: $redir");
|
||||
die();
|
||||
@@ -89,6 +123,10 @@ if ($_GET["google"] == "1") {
|
||||
}
|
||||
$url = "https://accounts.google.com/o/oauth2/auth";
|
||||
|
||||
// Generate a CSRF nonce and store it in the session
|
||||
$oauth_nonce = bin2hex(random_bytes(16));
|
||||
$_SESSION["oauth_nonce"] = $oauth_nonce;
|
||||
|
||||
// build the HTTP GET query
|
||||
$params = array(
|
||||
"response_type" => "code",
|
||||
@@ -96,7 +134,8 @@ if ($_GET["google"] == "1") {
|
||||
"redirect_uri" => "https://$DOMAIN/_login.php?google_callback=1",
|
||||
"scope" => "email openid profile",
|
||||
"state" => base64_encode(json_encode([
|
||||
"redir" => $_GET["redir"] ?? "/"
|
||||
"redir" => safe_redir($_GET["redir"] ?? "/"),
|
||||
"nonce" => $oauth_nonce
|
||||
]))
|
||||
);
|
||||
|
||||
@@ -107,16 +146,17 @@ if ($_GET["google"] == "1") {
|
||||
die();
|
||||
}
|
||||
if ($_GET["logout"] == "1") {
|
||||
$redir = $_GET["redir"] ?? "/";
|
||||
setcookie("auth_user", "", time() - 3600, "/");
|
||||
setcookie("auth_pass_b64", "", time() - 3600, "/");
|
||||
$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_destroy();
|
||||
header("Location: $redir");
|
||||
die();
|
||||
}
|
||||
if ($_GET["clear_session"] == "1") {
|
||||
session_destroy();
|
||||
$redir = $_GET["redir"] ?? "/";
|
||||
$redir = safe_redir($_GET["redir"] ?? "/");
|
||||
header("Location: $redir");
|
||||
die();
|
||||
}
|
||||
@@ -124,19 +164,19 @@ if (isset($_POST["user"])) {
|
||||
$valid = "";
|
||||
$user = trim(strtolower($_POST["user"]));
|
||||
$password = $_POST["password"];
|
||||
$userdata = json_decode(file_get_contents("/DATA/Usuarios/" . Sf($user) . ".json"), true);
|
||||
if (!isset($userdata["password_hash"])) {
|
||||
$user_filename = safe_username_to_filename($user);
|
||||
$userdata = ($user_filename !== "") ? json_decode(@file_get_contents("/DATA/Usuarios/" . $user_filename . ".json"), true) : null;
|
||||
if (!is_array($userdata) || !isset($userdata["password_hash"])) {
|
||||
$_GET["_result"] = "El usuario no existe.";
|
||||
}
|
||||
|
||||
$hash = $userdata["password_hash"];
|
||||
if (password_verify($password, $hash)) {
|
||||
} elseif (password_verify($password, $userdata["password_hash"])) {
|
||||
session_regenerate_id(true);
|
||||
$_SESSION['auth_user'] = $user;
|
||||
$_SESSION['auth_data'] = $userdata;
|
||||
$_SESSION['auth_ok'] = true;
|
||||
setcookie("auth_user", $user, time() + (86400 * 30), "/");
|
||||
setcookie("auth_pass_b64", base64_encode($password), time() + (86400 * 30), "/");
|
||||
$redir = $_GET["redir"] ?? "/";
|
||||
$cookie_options = ["expires" => time() + (86400 * 30), "path" => "/", "httponly" => true, "secure" => true, "samesite" => "Lax"];
|
||||
setcookie("auth_user", $user, $cookie_options);
|
||||
setcookie("auth_pass_b64", base64_encode($password), $cookie_options);
|
||||
$redir = safe_redir($_GET["redir"] ?? "/");
|
||||
header("Location: $redir");
|
||||
die();
|
||||
} else {
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
<?php
|
||||
ini_set("display_errors", 0);
|
||||
ini_set('memory_limit', '1G');
|
||||
|
||||
require_once __DIR__ . "/_incl/auth_redir.php";
|
||||
|
||||
ob_implicit_flush(true);
|
||||
ob_end_flush();
|
||||
ini_set('memory_limit', '1G');
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
|
||||
function safe_id_segment($value)
|
||||
|
||||
@@ -52,7 +52,7 @@ if ($centro_id === "") {
|
||||
}
|
||||
|
||||
$action = $_GET["action"] ?? ($_POST["action"] ?? "");
|
||||
$aulario_id = safe_id_segment(Sf($_GET["aulario"] ?? $_POST["aulario"] ?? ""));
|
||||
$aulario_id = safe_id_segment($_GET["aulario"] ?? $_POST["aulario"] ?? "");
|
||||
|
||||
// Validate aulario_id
|
||||
if ($aulario_id === "") {
|
||||
|
||||
@@ -24,7 +24,7 @@ function safe_aulario_config_path($centro_id, $aulario_id)
|
||||
return "/DATA/entreaulas/Centros/$centro/Aularios/$aulario.json";
|
||||
}
|
||||
|
||||
$aulario_id = safe_id_segment(Sf($_GET["id"] ?? ""));
|
||||
$aulario_id = safe_id_segment($_GET["id"] ?? "");
|
||||
$centro_id = safe_centro_id($_SESSION["auth_data"]["entreaulas"]["centro"] ?? "");
|
||||
$aulario_path = safe_aulario_config_path($centro_id, $aulario_id);
|
||||
$aulario = ($aulario_path && file_exists($aulario_path)) ? json_decode(file_get_contents($aulario_path), true) : null;
|
||||
|
||||
@@ -26,7 +26,7 @@ function safe_aulario_config_path($centro_id, $aulario_id)
|
||||
return "/DATA/entreaulas/Centros/$centro/Aularios/$aulario.json";
|
||||
}
|
||||
|
||||
$aulario_id = safe_id_segment(Sf($_GET["aulario"] ?? ""));
|
||||
$aulario_id = safe_id_segment($_GET["aulario"] ?? "");
|
||||
$centro_id = safe_centro_id($_SESSION["auth_data"]["entreaulas"]["centro"] ?? "");
|
||||
|
||||
if ($aulario_id === "" || $centro_id === "") {
|
||||
|
||||
@@ -28,9 +28,9 @@ function path_is_within($real_base, $real_path)
|
||||
return strpos($real_path, $base_prefix) === 0 || $real_path === rtrim($real_base, DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
$aulario_id = safe_id_segment(Sf($_GET["aulario"] ?? ""));
|
||||
$centro_id = safe_centro_id(Sf($_SESSION["auth_data"]["entreaulas"]["centro"] ?? ""));
|
||||
$alumno = safe_id_segment(Sf($_GET["alumno"] ?? ""));
|
||||
$aulario_id = safe_id_segment($_GET["aulario"] ?? "");
|
||||
$centro_id = safe_centro_id($_SESSION["auth_data"]["entreaulas"]["centro"] ?? "");
|
||||
$alumno = safe_id_segment($_GET["alumno"] ?? "");
|
||||
|
||||
if (empty($aulario_id) || empty($centro_id)) {
|
||||
require_once "_incl/pre-body.php";
|
||||
@@ -250,11 +250,10 @@ require_once "_incl/pre-body.php";
|
||||
|
||||
<?php
|
||||
// Show specific diary entry if requested
|
||||
$type = safe_id_segment(Sf($_GET["type"] ?? ""));
|
||||
$date = Sf($_GET["date"] ?? date("Y-m-d"));
|
||||
$type = safe_id_segment($_GET["type"] ?? "");
|
||||
$date = preg_replace('/[^0-9-]/', '', $_GET["date"] ?? date("Y-m-d"));
|
||||
|
||||
if (!empty($type) && !empty($date)) {
|
||||
$date = preg_replace('/[^0-9-]/', '', $date);
|
||||
$is_valid_date = false;
|
||||
if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {
|
||||
$date_obj = DateTime::createFromFormat('Y-m-d', $date);
|
||||
|
||||
@@ -796,7 +796,7 @@ switch ($view_action) {
|
||||
break;
|
||||
case "menu":
|
||||
// Menú del comedor (nuevo sistema, vista simplificada)
|
||||
$aulario_id = safe_id_segment(Sf($_GET["aulario"] ?? ''));
|
||||
$aulario_id = safe_id_segment($_GET["aulario"] ?? '');
|
||||
$centro_id = safe_centro_id($_SESSION["auth_data"]["entreaulas"]["centro"] ?? "");
|
||||
|
||||
$source_aulario_id = $aulario_id;
|
||||
@@ -805,7 +805,7 @@ switch ($view_action) {
|
||||
$aulario_path = safe_aulario_config_path($centro_id, $aulario_id);
|
||||
$aulario = ($aulario_path && file_exists($aulario_path)) ? json_decode(file_get_contents($aulario_path), true) : null;
|
||||
if ($aulario && !empty($aulario["shared_comedor_from"])) {
|
||||
$shared_from = safe_id_segment(Sf($aulario["shared_comedor_from"]));
|
||||
$shared_from = safe_id_segment($aulario["shared_comedor_from"]);
|
||||
$shared_aulario_path = safe_aulario_config_path($centro_id, $shared_from);
|
||||
if ($shared_aulario_path && file_exists($shared_aulario_path)) {
|
||||
$source_aulario_id = $shared_from;
|
||||
|
||||
@@ -7,13 +7,11 @@ if (in_array("entreaulas:docente", $_SESSION["auth_data"]["permissions"] ?? [])
|
||||
die("Access denied");
|
||||
}
|
||||
|
||||
$aulario_id = Sf($_GET["aulario"] ?? "");
|
||||
$centro_id = $_SESSION["auth_data"]["entreaulas"]["centro"] ?? "";
|
||||
$aulario_id = safe_path_segment($_GET["aulario"] ?? "");
|
||||
$centro_id = safe_path_segment($_SESSION["auth_data"]["entreaulas"]["centro"] ?? "");
|
||||
|
||||
// Sanitize and validate centro_id and aulario_id to prevent directory traversal
|
||||
$centro_id = safe_filename($centro_id);
|
||||
$aulario_id = safe_filename($aulario_id);
|
||||
if ($aulario_id === "" || $centro_id === "" || strpos($centro_id, '..') !== false || strpos($aulario_id, '..') !== false) {
|
||||
// Validate centro_id and aulario_id to prevent directory traversal
|
||||
if ($aulario_id === "" || $centro_id === "") {
|
||||
require_once "_incl/pre-body.php";
|
||||
?>
|
||||
<div class="card pad">
|
||||
@@ -461,8 +459,8 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
}
|
||||
|
||||
if ($action === "share_project") {
|
||||
$project_id = Sf($_POST["project_id"] ?? "");
|
||||
$target_aulario = safe_path_segment(Sf($_POST["target_aulario"] ?? ""));
|
||||
$project_id = safe_path_segment($_POST["project_id"] ?? "");
|
||||
$target_aulario = safe_path_segment($_POST["target_aulario"] ?? "");
|
||||
|
||||
if ($project_id !== "" && $target_aulario !== "" && $target_aulario !== $aulario_id) {
|
||||
// Only allow sharing local projects
|
||||
@@ -512,7 +510,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
if (in_array("entreaulas:proyectos:delete", $_SESSION["auth_data"]["permissions"] ?? []) === false) {
|
||||
$error = "No tienes permisos para borrar proyectos.";
|
||||
} else {
|
||||
$project_id = Sf($_POST["project_id"] ?? "");
|
||||
$project_id = safe_path_segment($_POST["project_id"] ?? "");
|
||||
if ($project_id !== "") {
|
||||
$project = load_project($proyectos_dir, $project_id);
|
||||
$project_dir = find_project_path($proyectos_dir, $project_id);
|
||||
@@ -538,7 +536,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
}
|
||||
|
||||
if ($action === "edit_project") {
|
||||
$project_id = Sf($_POST["project_id"] ?? "");
|
||||
$project_id = safe_path_segment($_POST["project_id"] ?? "");
|
||||
$name = trim($_POST["name"] ?? "");
|
||||
$description = sanitize_html($_POST["description"] ?? "");
|
||||
|
||||
@@ -559,15 +557,15 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
}
|
||||
|
||||
if ($action === "add_item") {
|
||||
$project_id = Sf($_POST["project_id"] ?? "");
|
||||
$item_type = Sf($_POST["item_type"] ?? "link");
|
||||
$item_name = trim(Sf($_POST["item_name"] ?? ""));
|
||||
$item_url = trim(Sf($_POST["item_url"] ?? ""));
|
||||
$item_content = sanitize_html(Sf($_POST["item_content"] ?? ""));
|
||||
$videocall_platform = Sf($_POST["videocall_platform"] ?? "jitsi");
|
||||
$videocall_room = trim(Sf($_POST["videocall_room"] ?? ""));
|
||||
$videocall_url = trim(Sf($_POST["videocall_url"] ?? ""));
|
||||
$source_aulario_param = Sf($_POST["source_aulario"] ?? "");
|
||||
$project_id = safe_path_segment($_POST["project_id"] ?? "");
|
||||
$item_type = safe_path_segment($_POST["item_type"] ?? "link");
|
||||
$item_name = trim($_POST["item_name"] ?? "");
|
||||
$item_url = trim($_POST["item_url"] ?? "");
|
||||
$item_content = sanitize_html($_POST["item_content"] ?? "");
|
||||
$videocall_platform = safe_path_segment($_POST["videocall_platform"] ?? "jitsi");
|
||||
$videocall_room = trim($_POST["videocall_room"] ?? "");
|
||||
$videocall_url = trim($_POST["videocall_url"] ?? "");
|
||||
$source_aulario_param = safe_path_segment($_POST["source_aulario"] ?? "");
|
||||
|
||||
// Determine which directory to use and permission level
|
||||
$working_dir = $proyectos_dir;
|
||||
@@ -579,10 +577,10 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
// Validate the link
|
||||
$linked_projects = $aulario["linked_projects"] ?? [];
|
||||
foreach ($linked_projects as $link) {
|
||||
if ((Sf($link["source_aulario"] ?? "") === $source_aulario_param) &&
|
||||
(Sf($link["project_id"] ?? "") === $project_id)
|
||||
if ((($link["source_aulario"] ?? "") === $source_aulario_param) &&
|
||||
(($link["project_id"] ?? "") === $project_id)
|
||||
) {
|
||||
$permission = Sf($link["permission"] ?? "read_only");
|
||||
$permission = safe_path_segment($link["permission"] ?? "read_only");
|
||||
if ($permission === "full_edit") {
|
||||
$working_dir = $proyectos_dir;
|
||||
} elseif ($permission === "request_edit") {
|
||||
@@ -777,8 +775,8 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
}
|
||||
|
||||
if ($action === "approve_change" || $action === "reject_change") {
|
||||
$change_id = safe_filename(Sf($_POST["change_id"] ?? ""));
|
||||
$project_id = Sf($_POST["project_id"] ?? "");
|
||||
$change_id = safe_filename($_POST["change_id"] ?? "");
|
||||
$project_id = safe_path_segment($_POST["project_id"] ?? "");
|
||||
|
||||
if (!empty($change_id) && !empty($project_id)) {
|
||||
$project_dir = find_project_path($proyectos_dir, $project_id);
|
||||
@@ -841,7 +839,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
}
|
||||
|
||||
if (in_array(($item["type"] ?? ""), ["file", "pdf_secure"], true) && !empty($change_data["pending_filename"])) {
|
||||
$pending_filename = safe_filename(Sf($change_data["pending_filename"]));
|
||||
$pending_filename = safe_filename($change_data["pending_filename"]);
|
||||
$pending_file = safe_join_file($pending_dir, $pending_filename);
|
||||
$target_file = safe_join_file($project_dir, $pending_filename);
|
||||
if ($pending_file && $target_file && file_exists($pending_file)) {
|
||||
@@ -850,7 +848,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
}
|
||||
rename($pending_file, $target_file);
|
||||
if (!empty($item["filename"])) {
|
||||
$old_path = safe_join_file($project_dir, Sf($item["filename"]));
|
||||
$old_path = safe_join_file($project_dir, $item["filename"]);
|
||||
if ($old_path && file_exists($old_path)) {
|
||||
unlink($old_path);
|
||||
if (file_exists($old_path . ".eadat")) {
|
||||
@@ -859,7 +857,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
}
|
||||
}
|
||||
$item["filename"] = $pending_filename;
|
||||
$item["original_name"] = Sf($change_data["original_filename"] ?? $pending_filename);
|
||||
$item["original_name"] = safe_filename($change_data["original_filename"] ?? $pending_filename);
|
||||
|
||||
$file_meta = [
|
||||
"id" => $item_id,
|
||||
@@ -907,7 +905,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
$item["room"] = $change_data["item_room"] ?? "";
|
||||
} elseif (in_array($change_data["item_type"], ["file", "pdf_secure"], true) && !empty($change_data["pending_filename"])) {
|
||||
// Move file from pending to project directory
|
||||
$pending_filename = safe_filename(Sf($change_data["pending_filename"]));
|
||||
$pending_filename = safe_filename($change_data["pending_filename"]);
|
||||
$pending_file = safe_join_file($pending_dir, $pending_filename);
|
||||
$target_file = safe_join_file($project_dir, $pending_filename);
|
||||
|
||||
@@ -917,12 +915,12 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
}
|
||||
rename($pending_file, $target_file);
|
||||
$item["filename"] = $pending_filename;
|
||||
$item["original_name"] = Sf($change_data["original_filename"] ?? $pending_filename);
|
||||
$item["original_name"] = safe_filename($change_data["original_filename"] ?? $pending_filename);
|
||||
|
||||
$file_meta = [
|
||||
"id" => $item_id,
|
||||
"name" => Sf($change_data["item_name"]),
|
||||
"type" => Sf($change_data["item_type"]),
|
||||
"name" => $change_data["item_name"],
|
||||
"type" => $change_data["item_type"],
|
||||
"original_name" => $item["original_name"],
|
||||
"created_at" => $item["created_at"]
|
||||
];
|
||||
@@ -943,7 +941,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
} else {
|
||||
// Reject - just delete pending file if exists
|
||||
if (!empty($change_data["pending_filename"])) {
|
||||
$pending_file = safe_join_file($pending_dir, Sf($change_data["pending_filename"]));
|
||||
$pending_file = safe_join_file($pending_dir, safe_filename($change_data["pending_filename"]));
|
||||
if ($pending_file && file_exists($pending_file)) {
|
||||
unlink($pending_file);
|
||||
}
|
||||
@@ -960,9 +958,9 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
}
|
||||
|
||||
if ($action === "delete_item") {
|
||||
$project_id = Sf($_POST["project_id"] ?? "");
|
||||
$item_id = Sf($_POST["item_id"] ?? "");
|
||||
$source_aulario_param = Sf($_POST["source_aulario"] ?? "");
|
||||
$project_id = safe_path_segment($_POST["project_id"] ?? "");
|
||||
$item_id = safe_path_segment($_POST["item_id"] ?? "");
|
||||
$source_aulario_param = safe_path_segment($_POST["source_aulario"] ?? "");
|
||||
|
||||
// Determine which directory to use based on whether this is a linked project
|
||||
$working_dir = $proyectos_dir;
|
||||
@@ -1069,15 +1067,15 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
}
|
||||
|
||||
if ($action === "edit_item") {
|
||||
$project_id = Sf($_POST["project_id"] ?? "");
|
||||
$item_id = Sf($_POST["item_id"] ?? "");
|
||||
$item_name = Sf(trim($_POST["item_name"] ?? ""));
|
||||
$item_url = Sf(trim($_POST["item_url"] ?? ""));
|
||||
$item_content = Sf(sanitize_html($_POST["item_content"] ?? ""));
|
||||
$videocall_platform = Sf($_POST["edit_videocall_platform"] ?? "jitsi");
|
||||
$videocall_room = Sf(trim($_POST["edit_videocall_room"] ?? ""));
|
||||
$videocall_url = Sf(trim($_POST["edit_videocall_url"] ?? ""));
|
||||
$source_aulario_param = Sf($_POST["source_aulario"] ?? "");
|
||||
$project_id = safe_path_segment($_POST["project_id"] ?? "");
|
||||
$item_id = safe_path_segment($_POST["item_id"] ?? "");
|
||||
$item_name = trim($_POST["item_name"] ?? "");
|
||||
$item_url = trim($_POST["item_url"] ?? "");
|
||||
$item_content = sanitize_html($_POST["item_content"] ?? "");
|
||||
$videocall_platform = safe_path_segment($_POST["edit_videocall_platform"] ?? "jitsi");
|
||||
$videocall_room = trim($_POST["edit_videocall_room"] ?? "");
|
||||
$videocall_url = trim($_POST["edit_videocall_url"] ?? "");
|
||||
$source_aulario_param = safe_path_segment($_POST["source_aulario"] ?? "");
|
||||
|
||||
$working_dir = $proyectos_dir;
|
||||
$permission = "full_edit";
|
||||
|
||||
@@ -14,7 +14,7 @@ function safe_username($value)
|
||||
|
||||
switch ($_GET['form'] ?? '') {
|
||||
case 'save_password':
|
||||
$username = safe_username(Sf($_POST['username'] ?? ''));
|
||||
$username = safe_username($_POST['username'] ?? '');
|
||||
$new_password = $_POST['new_password'] ?? '';
|
||||
$confirm_password = $_POST['confirm_password'] ?? '';
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ function safe_aulario_id($value)
|
||||
|
||||
switch ($_GET['form'] ?? '') {
|
||||
case 'save_edit':
|
||||
$username = safe_username(Sf($_POST['username'] ?? ''));
|
||||
$username = safe_username($_POST['username'] ?? '');
|
||||
if (empty($username)) {
|
||||
die("Nombre de usuario no proporcionado.");
|
||||
}
|
||||
@@ -175,7 +175,7 @@ switch ($_GET['action'] ?? '') {
|
||||
break;
|
||||
case 'edit':
|
||||
require_once "_incl/pre-body.php";
|
||||
$username = safe_username(Sf($_GET['user'] ?? ''));
|
||||
$username = safe_username($_GET['user'] ?? '');
|
||||
if (empty($username)) {
|
||||
die("Nombre de usuario inválido.");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user