diff --git a/public_html/entreaulas/_filefetch.php b/public_html/entreaulas/_filefetch.php index 57af825..c3df766 100755 --- a/public_html/entreaulas/_filefetch.php +++ b/public_html/entreaulas/_filefetch.php @@ -5,11 +5,31 @@ ob_end_flush(); ini_set('memory_limit', '1G'); header("Access-Control-Allow-Origin: *"); -switch ($_GET["type"]) { +function safe_id_segment($value) +{ + $value = basename((string)$value); + return preg_replace('/[^A-Za-z0-9_-]/', '', $value); +} + +function safe_centro_id($value) +{ + return preg_replace('/[^0-9]/', '', (string)$value); +} + +function safe_filename($name) +{ + $name = basename((string)$name); + $name = preg_replace('/[^A-Za-z0-9._-]/', '_', $name); + $name = ltrim($name, '.'); + return $name; +} + +$type = $_GET["type"] ?? ""; +switch ($type) { case "alumno_photo": - $centro = basename($_GET["centro"] ?? ''); - $aulario = basename($_GET["aulario"] ?? ''); - $alumno = basename($_GET["alumno"] ?? ''); + $centro = safe_centro_id($_GET["centro"] ?? ''); + $aulario = safe_id_segment($_GET["aulario"] ?? ''); + $alumno = safe_id_segment($_GET["alumno"] ?? ''); // Additional validation to prevent empty names if (empty($centro) || empty($aulario) || empty($alumno)) { header("HTTP/1.1 403 Forbidden"); @@ -18,15 +38,23 @@ switch ($_GET["type"]) { $relpath = "entreaulas/Centros/$centro/Aularios/$aulario/Alumnos/$alumno/photo.jpg"; break; case "panel_actividades": - $centro = str_replace('..', '_', $_GET["centro"] ?? ''); - $activity = str_replace('..', '_', $_GET["activity"] ?? ''); + $centro = safe_centro_id($_GET["centro"] ?? ''); + $activity = safe_id_segment($_GET["activity"] ?? ''); + if (empty($centro) || empty($activity)) { + header("HTTP/1.1 400 Bad Request"); + die("Invalid parameters"); + } $relpath = "entreaulas/Centros/$centro/Panel/Actividades/$activity/photo.jpg"; break; case "comedor_image": - $centro = str_replace('..', '_', $_GET["centro"] ?? ''); - $aulario = str_replace('..', '_', $_GET["aulario"] ?? ''); + $centro = safe_centro_id($_GET["centro"] ?? ''); + $aulario = safe_id_segment($_GET["aulario"] ?? ''); $date = preg_replace('/[^0-9-]/', '', $_GET["date"] ?? ''); - $file = basename($_GET["file"] ?? ''); + $file = safe_filename($_GET["file"] ?? ''); + if (empty($centro) || empty($aulario) || empty($file)) { + header("HTTP/1.1 400 Bad Request"); + die("Invalid parameters"); + } if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) { header("HTTP/1.1 400 Bad Request"); die("Invalid date"); @@ -36,9 +64,13 @@ switch ($_GET["type"]) { $relpath = "entreaulas/Centros/$centro/Aularios/$aulario/Comedor/$ym/$day/$file"; break; case "proyecto_file": - $centro = str_replace('..', '_', $_GET["centro"] ?? ''); - $project = str_replace('..', '_', $_GET["project"] ?? ''); - $file = basename($_GET["file"] ?? ''); + $centro = safe_centro_id($_GET["centro"] ?? ''); + $project = safe_id_segment($_GET["project"] ?? ''); + $file = safe_filename($_GET["file"] ?? ''); + if (empty($centro) || empty($project) || empty($file)) { + header("HTTP/1.1 400 Bad Request"); + die("Invalid parameters"); + } // Ensure no directory traversal if (strpos($file, '..') !== false || strpos($file, '/') !== false || strpos($file, '\\') !== false) { header("HTTP/1.1 400 Bad Request"); @@ -73,6 +105,9 @@ switch ($_GET["type"]) { $path = $project_dir . "/" . $file; $uripath = str_replace("/DATA", "", $path); break; + default: + header("HTTP/1.1 400 Bad Request"); + die("Invalid type"); } if (!isset($path)) { $path = "/DATA/$relpath"; @@ -84,7 +119,8 @@ if (!isset($uripath)) { // Validate that the resolved path is within /DATA directory $real_path = realpath($path); $real_base = realpath("/DATA"); -if ($real_path === false || $real_base === false || strpos($real_path, $real_base) !== 0) { +$real_base_prefix = $real_base !== false ? rtrim($real_base, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : null; +if ($real_path === false || $real_base === false || $real_base_prefix === null || strpos($real_path, $real_base_prefix) !== 0) { header("HTTP/1.1 403 Forbidden"); die("Access denied"); } @@ -96,7 +132,7 @@ if (!file_exists($real_path) || !is_file($real_path)) { $mime = mime_content_type($real_path); // Check if thumbnail is requested -if (file_exists($real_path . ".thumbnail") && $_GET["thumbnail"] == "1") { +if (file_exists($real_path . ".thumbnail") && (($_GET["thumbnail"] ?? "") === "1")) { $real_path .= ".thumbnail"; $uripath .= ".thumbnail"; $mime = "image/jpeg"; diff --git a/public_html/entreaulas/alumnos.php b/public_html/entreaulas/alumnos.php index 70035b5..c47b9ad 100644 --- a/public_html/entreaulas/alumnos.php +++ b/public_html/entreaulas/alumnos.php @@ -7,8 +7,37 @@ if (!in_array("entreaulas:docente", $_SESSION["auth_data"]["permissions"] ?? []) die("Access denied"); } -$aulario_id = $_GET["aulario"] ?? ""; -$centro_id = $_SESSION["auth_data"]["entreaulas"]["centro"] ?? ""; +function safe_id_segment($value) +{ + $value = basename((string)$value); + return preg_replace('/[^A-Za-z0-9_-]/', '', $value); +} + +function safe_centro_id($value) +{ + return preg_replace('/[^0-9]/', '', (string)$value); +} + +function safe_alumno_name($value) +{ + $value = basename((string)$value); + $value = trim($value); + $value = preg_replace('/[\x00-\x1F\x7F]/u', '', $value); + $value = str_replace(['/', '\\'], '', $value); + return $value; +} + +function path_is_within($real_base, $real_path) +{ + if ($real_base === false || $real_path === false) { + return false; + } + $base_prefix = rtrim($real_base, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; + return strpos($real_path, $base_prefix) === 0 || $real_path === rtrim($real_base, DIRECTORY_SEPARATOR); +} + +$aulario_id = safe_id_segment($_GET["aulario"] ?? ""); +$centro_id = safe_centro_id($_SESSION["auth_data"]["entreaulas"]["centro"] ?? ""); if (empty($aulario_id) || empty($centro_id)) { require_once "_incl/pre-body.php"; @@ -22,9 +51,6 @@ if (empty($aulario_id) || empty($centro_id)) { exit; } -$aulario_id = basename($aulario_id); -$centro_id = basename($centro_id); - // Validate paths with realpath $base_path = "/DATA/entreaulas/Centros"; $real_base = realpath($base_path); @@ -53,7 +79,11 @@ switch ($_GET["form"] ?? '') { } // Sanitize filename - $nombre_safe = basename($nombre); + $nombre_safe = safe_alumno_name($nombre); + if ($nombre_safe === "") { + header("Location: ?aulario=" . urlencode($aulario_id) . "&_result=" . urlencode("Nombre inválido")); + exit; + } $alumno_path = "$alumnos_base_path/$nombre_safe"; // Validate path with realpath (after potential creation) @@ -62,7 +92,7 @@ switch ($_GET["form"] ?? '') { } $real_alumnos_base = realpath($alumnos_base_path); - if ($real_alumnos_base === false || strpos($real_alumnos_base, $real_base) !== 0) { + if (!path_is_within($real_base, $real_alumnos_base)) { header("Location: ?aulario=" . urlencode($aulario_id) . "&_result=" . urlencode("Error: Ruta inválida")); exit; } @@ -92,7 +122,7 @@ switch ($_GET["form"] ?? '') { exit; case 'edit': - $nombre_old = basename($_POST['nombre_old'] ?? ''); + $nombre_old = safe_alumno_name($_POST['nombre_old'] ?? ''); $nombre_new = trim($_POST['nombre_new'] ?? ''); if (empty($nombre_old) || empty($nombre_new)) { @@ -100,13 +130,27 @@ switch ($_GET["form"] ?? '') { exit; } - $nombre_new_safe = basename($nombre_new); + $nombre_new_safe = safe_alumno_name($nombre_new); + if ($nombre_new_safe === "") { + header("Location: ?aulario=" . urlencode($aulario_id) . "&_result=" . urlencode("Nombre inválido")); + exit; + } $alumno_old_path = "$alumnos_base_path/$nombre_old"; $alumno_new_path = "$alumnos_base_path/$nombre_new_safe"; + + if (!is_dir($alumnos_base_path)) { + header("Location: ?aulario=" . urlencode($aulario_id) . "&_result=" . urlencode("Alumno no encontrado")); + exit; + } + $real_alumnos_base = realpath($alumnos_base_path); + if (!path_is_within($real_base, $real_alumnos_base)) { + header("Location: ?aulario=" . urlencode($aulario_id) . "&_result=" . urlencode("Ruta inválida")); + exit; + } // Validate paths with realpath $real_old_path = realpath($alumno_old_path); - if ($real_old_path === false || strpos($real_old_path, $real_base) !== 0) { + if (!path_is_within($real_alumnos_base, $real_old_path)) { header("Location: ?aulario=" . urlencode($aulario_id) . "&_result=" . urlencode("Alumno no encontrado")); exit; } @@ -144,17 +188,27 @@ switch ($_GET["form"] ?? '') { exit; case 'delete': - $nombre = basename($_POST['nombre'] ?? ''); + $nombre = safe_alumno_name($_POST['nombre'] ?? ''); if (empty($nombre)) { header("Location: ?aulario=" . urlencode($aulario_id) . "&_result=" . urlencode("Nombre inválido")); exit; } $alumno_path = "$alumnos_base_path/$nombre"; + + if (!is_dir($alumnos_base_path)) { + header("Location: ?aulario=" . urlencode($aulario_id) . "&_result=" . urlencode("Alumno no encontrado")); + exit; + } + $real_alumnos_base = realpath($alumnos_base_path); + if (!path_is_within($real_base, $real_alumnos_base)) { + header("Location: ?aulario=" . urlencode($aulario_id) . "&_result=" . urlencode("Ruta inválida")); + exit; + } // Validate path with realpath $real_alumno_path = realpath($alumno_path); - if ($real_alumno_path === false || strpos($real_alumno_path, $real_base) !== 0) { + if (!path_is_within($real_alumnos_base, $real_alumno_path)) { header("Location: ?aulario=" . urlencode($aulario_id) . "&_result=" . urlencode("Alumno no encontrado")); exit; } @@ -198,7 +252,7 @@ switch ($_GET["action"] ?? '') { exit; case 'edit': - $nombre = basename($_GET['alumno'] ?? ''); + $nombre = safe_alumno_name($_GET['alumno'] ?? ''); $alumno_path = "$alumnos_base_path/$nombre"; if (empty($nombre) || !file_exists($alumno_path)) { @@ -246,7 +300,7 @@ switch ($_GET["action"] ?? '') { exit; case 'delete': - $nombre = basename($_GET['alumno'] ?? ''); + $nombre = safe_alumno_name($_GET['alumno'] ?? ''); $alumno_path = "$alumnos_base_path/$nombre"; if (empty($nombre) || !file_exists($alumno_path)) { diff --git a/public_html/entreaulas/api/comedor.php b/public_html/entreaulas/api/comedor.php index 6634234..10b0a91 100644 --- a/public_html/entreaulas/api/comedor.php +++ b/public_html/entreaulas/api/comedor.php @@ -3,20 +3,56 @@ header("Content-Type: application/json; charset=utf-8"); require_once __DIR__ . "/../_incl/tools.security.php"; require_once __DIR__ . "/../_incl/auth_redir.php"; +function safe_id_segment($value) { + $value = basename((string)$value); + return preg_replace('/[^A-Za-z0-9_-]/', '', $value); +} + +function safe_centro_id($value) { + return preg_replace('/[^0-9]/', '', (string)$value); +} + +function safe_aulario_config_path($centro_id, $aulario_id) { + $centro = safe_centro_id($centro_id); + $aulario = safe_id_segment($aulario_id); + if ($centro === '' || $aulario === '') { + return null; + } + return "/DATA/entreaulas/Centros/$centro/Aularios/$aulario.json"; +} + +function menu_types_path($centro_id, $aulario_id) { + $centro = safe_centro_id($centro_id); + $aulario = safe_id_segment($aulario_id); + if ($centro === '' || $aulario === '') { + return null; + } + return "/DATA/entreaulas/Centros/$centro/Aularios/$aulario/Comedor-MenuTypes.json"; +} + +function comedor_day_base_dir($centro_id, $aulario_id, $ym, $day) { + $centro = safe_centro_id($centro_id); + $aulario = safe_id_segment($aulario_id); + if ($centro === '' || $aulario === '') { + return null; + } + return "/DATA/entreaulas/Centros/$centro/Aularios/$aulario/Comedor/$ym/$day"; +} + // Check permissions if (!in_array("entreaulas:docente", $_SESSION["auth_data"]["permissions"] ?? [])) { http_response_code(403); die(json_encode(["error" => "Access denied", "code" => "FORBIDDEN"])); } -$centro_id = $_SESSION["auth_data"]["entreaulas"]["centro"] ?? ""; +$centro_id = safe_centro_id($_SESSION["auth_data"]["entreaulas"]["centro"] ?? ""); if ($centro_id === "") { http_response_code(400); die(json_encode(["error" => "Centro not found in session", "code" => "INVALID_SESSION"])); } $action = $_GET["action"] ?? ($_POST["action"] ?? ""); -$aulario_id = Sf($_GET["aulario"] ?? $_POST["aulario"] ?? ""); +$aulario_id = safe_id_segment(Sf($_GET["aulario"] ?? $_POST["aulario"] ?? "")); // Validate aulario_id if ($aulario_id === "") { @@ -26,22 +62,23 @@ if ($aulario_id === "") { // Verify that the user has access to this aulario $userAulas = $_SESSION["auth_data"]["entreaulas"]["aulas"] ?? []; -if (!in_array($aulario_id, $userAulas)) { +$userAulas = array_values(array_filter(array_map('safe_id_segment', $userAulas))); +if (!in_array($aulario_id, $userAulas, true)) { http_response_code(403); die(json_encode(["error" => "Access denied to this aulario", "code" => "FORBIDDEN"])); } -$aulario_path = "/DATA/entreaulas/Centros/$centro_id/Aularios/$aulario_id.json"; -$aulario = file_exists($aulario_path) ? json_decode(file_get_contents($aulario_path), true) : null; +$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; // Handle shared comedor data $source_aulario_id = $aulario_id; $is_shared = false; if ($aulario && !empty($aulario["shared_comedor_from"])) { - $shared_from = $aulario["shared_comedor_from"]; - $shared_aulario_path = "/DATA/entreaulas/Centros/$centro_id/Aularios/$shared_from.json"; - if (file_exists($shared_aulario_path)) { - $source_aulario_id = Sf($shared_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; $is_shared = true; } } @@ -51,12 +88,16 @@ $canEdit = in_array("sysadmin:access", $_SESSION["auth_data"]["permissions"] ?? // Helper functions function get_menu_types($centro_id, $source_aulario_id) { - $menuTypesPath = "/DATA/entreaulas/Centros/$centro_id/Aularios/$source_aulario_id/Comedor-MenuTypes.json"; + $menuTypesPath = menu_types_path($centro_id, $source_aulario_id); $defaultMenuTypes = [ ["id" => "basal", "label" => "Menú basal", "color" => "#0d6efd"], ["id" => "vegetariano", "label" => "Menú vegetariano", "color" => "#198754"], ["id" => "alergias", "label" => "Menú alergias", "color" => "#dc3545"], ]; + + if ($menuTypesPath === null) { + return $defaultMenuTypes; + } if (!file_exists($menuTypesPath)) { if (!is_dir(dirname($menuTypesPath))) { @@ -146,7 +187,7 @@ function handle_get_menu() { global $centro_id, $source_aulario_id; $date = $_GET["date"] ?? date("Y-m-d"); - $menuTypeId = $_GET["menu"] ?? ""; + $menuTypeId = safe_id_segment($_GET["menu"] ?? ""); // Validate date $dateObj = DateTime::createFromFormat("Y-m-d", $date); @@ -172,7 +213,11 @@ function handle_get_menu() { // Get menu data $ym = $dateObj->format("Y-m"); $day = $dateObj->format("d"); - $baseDir = "/DATA/entreaulas/Centros/$centro_id/Aularios/$source_aulario_id/Comedor/$ym/$day"; + $baseDir = comedor_day_base_dir($centro_id, $source_aulario_id, $ym, $day); + if ($baseDir === null) { + http_response_code(400); + die(json_encode(["error" => "Invalid path parameters", "code" => "INVALID_PATH"])); + } $dataPath = "$baseDir/_datos.json"; $menuData = [ @@ -212,7 +257,7 @@ function handle_save_menu() { } $date = $input["date"] ?? date("Y-m-d"); - $menuTypeId = $input["menu_type"] ?? ""; + $menuTypeId = safe_id_segment($input["menu_type"] ?? ""); $plates = $input["plates"] ?? []; // Validate date @@ -240,7 +285,11 @@ function handle_save_menu() { // Get existing menu data $ym = $dateObj->format("Y-m"); $day = $dateObj->format("d"); - $baseDir = "/DATA/entreaulas/Centros/$centro_id/Aularios/$source_aulario_id/Comedor/$ym/$day"; + $baseDir = comedor_day_base_dir($centro_id, $source_aulario_id, $ym, $day); + if ($baseDir === null) { + http_response_code(400); + die(json_encode(["error" => "Invalid path parameters", "code" => "INVALID_PATH"])); + } $dataPath = "$baseDir/_datos.json"; $menuData = [ @@ -292,7 +341,7 @@ function handle_add_menu_type() { $input = $_POST; } - $newId = strtolower(trim($input["id"] ?? "")); + $newId = safe_id_segment(strtolower(trim($input["id"] ?? ""))); $newLabel = trim($input["label"] ?? ""); $newColor = trim($input["color"] ?? "#0d6efd"); @@ -301,7 +350,11 @@ function handle_add_menu_type() { die(json_encode(["error" => "id and label are required", "code" => "MISSING_PARAM"])); } - $menuTypesPath = "/DATA/entreaulas/Centros/$centro_id/Aularios/$source_aulario_id/Comedor-MenuTypes.json"; + $menuTypesPath = menu_types_path($centro_id, $source_aulario_id); + if ($menuTypesPath === null) { + http_response_code(400); + die(json_encode(["error" => "Invalid path parameters", "code" => "INVALID_PATH"])); + } $menuTypes = get_menu_types($centro_id, $source_aulario_id); // Check if already exists @@ -330,14 +383,18 @@ function handle_delete_menu_type() { $input = $_POST; } - $deleteId = trim($input["id"] ?? ""); + $deleteId = safe_id_segment(trim($input["id"] ?? "")); if ($deleteId === "") { http_response_code(400); die(json_encode(["error" => "id is required", "code" => "MISSING_PARAM"])); } - $menuTypesPath = "/DATA/entreaulas/Centros/$centro_id/Aularios/$source_aulario_id/Comedor-MenuTypes.json"; + $menuTypesPath = menu_types_path($centro_id, $source_aulario_id); + if ($menuTypesPath === null) { + http_response_code(400); + die(json_encode(["error" => "Invalid path parameters", "code" => "INVALID_PATH"])); + } $menuTypes = get_menu_types($centro_id, $source_aulario_id); $deleted = false; @@ -371,7 +428,7 @@ function handle_rename_menu_type() { $input = $_POST; } - $renameId = trim($input["id"] ?? ""); + $renameId = safe_id_segment(trim($input["id"] ?? "")); $newLabel = trim($input["label"] ?? ""); $newColor = trim($input["color"] ?? ""); @@ -380,7 +437,11 @@ function handle_rename_menu_type() { die(json_encode(["error" => "id and label are required", "code" => "MISSING_PARAM"])); } - $menuTypesPath = "/DATA/entreaulas/Centros/$centro_id/Aularios/$source_aulario_id/Comedor-MenuTypes.json"; + $menuTypesPath = menu_types_path($centro_id, $source_aulario_id); + if ($menuTypesPath === null) { + http_response_code(400); + die(json_encode(["error" => "Invalid path parameters", "code" => "INVALID_PATH"])); + } $menuTypes = get_menu_types($centro_id, $source_aulario_id); $found = false; diff --git a/public_html/entreaulas/aulario.php b/public_html/entreaulas/aulario.php index 238acd4..f7a3a24 100644 --- a/public_html/entreaulas/aulario.php +++ b/public_html/entreaulas/aulario.php @@ -3,9 +3,39 @@ require_once "_incl/auth_redir.php"; require_once "_incl/pre-body.php"; require_once "_incl/tools.security.php"; -$aulario_id = Sf($_GET["id"]); -$centro_id = $_SESSION["auth_data"]["entreaulas"]["centro"]; -$aulario = json_decode(file_get_contents("/DATA/entreaulas/Centros/$centro_id/Aularios/$aulario_id.json"), true); +function safe_id_segment($value) +{ + $value = basename((string)$value); + return preg_replace('/[^A-Za-z0-9_-]/', '', $value); +} + +function safe_centro_id($value) +{ + return preg_replace('/[^0-9]/', '', (string)$value); +} + +function safe_aulario_config_path($centro_id, $aulario_id) +{ + $centro = safe_centro_id($centro_id); + $aulario = safe_id_segment($aulario_id); + if ($centro === '' || $aulario === '') { + return null; + } + return "/DATA/entreaulas/Centros/$centro/Aularios/$aulario.json"; +} + +$aulario_id = safe_id_segment(Sf($_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; + +if (!$aulario || !is_array($aulario)) { +?> +
+

Aulario no encontrado

+

No se ha podido cargar la configuración del aulario.

+
+
diff --git a/public_html/entreaulas/comedor.php b/public_html/entreaulas/comedor.php index 403ff53..e9c103d 100644 --- a/public_html/entreaulas/comedor.php +++ b/public_html/entreaulas/comedor.php @@ -5,8 +5,29 @@ if (in_array("entreaulas:docente", $_SESSION["auth_data"]["permissions"] ?? []) die("Access denied"); } -$aulario_id = Sf($_GET["aulario"] ?? ""); -$centro_id = $_SESSION["auth_data"]["entreaulas"]["centro"] ?? ""; +function safe_id_segment($value) +{ + $value = basename((string)$value); + return preg_replace('/[^A-Za-z0-9_-]/', '', $value); +} + +function safe_centro_id($value) +{ + return preg_replace('/[^0-9]/', '', (string)$value); +} + +function safe_aulario_config_path($centro_id, $aulario_id) +{ + $centro = safe_centro_id($centro_id); + $aulario = safe_id_segment($aulario_id); + if ($centro === "" || $aulario === "") { + return null; + } + return "/DATA/entreaulas/Centros/$centro/Aularios/$aulario.json"; +} + +$aulario_id = safe_id_segment(Sf($_GET["aulario"] ?? "")); +$centro_id = safe_centro_id($_SESSION["auth_data"]["entreaulas"]["centro"] ?? ""); if ($aulario_id === "" || $centro_id === "") { require_once "_incl/pre-body.php"; @@ -20,18 +41,18 @@ if ($aulario_id === "" || $centro_id === "") { exit; } -$aulario_path = "/DATA/entreaulas/Centros/$centro_id/Aularios/$aulario_id.json"; -$aulario = file_exists($aulario_path) ? json_decode(file_get_contents($aulario_path), true) : null; +$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; // Check if this aulario shares comedor data from another aulario $source_aulario_id = $aulario_id; // Default to current aulario $is_shared = false; if ($aulario && !empty($aulario["shared_comedor_from"])) { - $shared_from = $aulario["shared_comedor_from"]; - $shared_aulario_path = "/DATA/entreaulas/Centros/$centro_id/Aularios/$shared_from.json"; - if (file_exists($shared_aulario_path)) { - $source_aulario_id = Sf($shared_from); - $source_aulario_name = file_exists($shared_aulario_path) ? json_decode(file_get_contents($shared_aulario_path), true)["name"] ?? $shared_from : $shared_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; + $source_aulario_name = json_decode(file_get_contents($shared_aulario_path), true)["name"] ?? $shared_from; $is_shared = true; } } @@ -153,7 +174,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST" && $canEdit) { $action = $_POST["action"] ?? ""; if ($action === "add_type") { - $newId = strtolower(trim($_POST["new_type_id"] ?? "")); + $newId = safe_id_segment(strtolower(trim($_POST["new_type_id"] ?? ""))); $newLabel = trim($_POST["new_type_label"] ?? ""); $newColor = trim($_POST["new_type_color"] ?? "#0d6efd"); if ($newId !== "" && $newLabel !== "") { @@ -174,7 +195,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST" && $canEdit) { } if ($action === "delete_type") { - $deleteId = trim($_POST["delete_type_id"] ?? ""); + $deleteId = safe_id_segment(trim($_POST["delete_type_id"] ?? "")); if ($deleteId !== "") { $deleted = false; $newMenuTypes = []; @@ -197,7 +218,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST" && $canEdit) { } if ($action === "rename_type") { - $renameId = trim($_POST["rename_type_id"] ?? ""); + $renameId = safe_id_segment(trim($_POST["rename_type_id"] ?? "")); $newLabel = trim($_POST["rename_type_label"] ?? ""); $newColor = trim($_POST["rename_type_color"] ?? ""); if ($renameId !== "" && $newLabel !== "") { @@ -219,7 +240,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST" && $canEdit) { } if ($action === "save") { - $menuTypeId = $_POST["menu_type"] ?? $menuTypeId; + $menuTypeId = safe_id_segment($_POST["menu_type"] ?? $menuTypeId); if (!isset($menuData["menus"][$menuTypeId])) { $menuData["menus"][$menuTypeId] = blank_menu(); } @@ -263,11 +284,15 @@ $nextDate = (clone $dateObj)->modify("+1 day")->format("Y-m-d"); $userAulas = $_SESSION["auth_data"]["entreaulas"]["aulas"] ?? []; $aulaOptions = []; foreach ($userAulas as $aulaId) { - $aulaPath = "/DATA/entreaulas/Centros/$centro_id/Aularios/$aulaId.json"; + $aulaIdSafe = safe_id_segment($aulaId); + if ($aulaIdSafe === "") { + continue; + } + $aulaPath = "/DATA/entreaulas/Centros/$centro_id/Aularios/$aulaIdSafe.json"; $aulaData = file_exists($aulaPath) ? json_decode(file_get_contents($aulaPath), true) : null; $aulaOptions[] = [ - "id" => $aulaId, - "name" => $aulaData["name"] ?? $aulaId + "id" => $aulaIdSafe, + "name" => $aulaData["name"] ?? $aulaIdSafe ]; } require_once "_incl/pre-body.php"; diff --git a/public_html/entreaulas/diario.php b/public_html/entreaulas/diario.php index b46c2ad..9936cbd 100644 --- a/public_html/entreaulas/diario.php +++ b/public_html/entreaulas/diario.php @@ -8,9 +8,29 @@ if (!in_array("entreaulas:docente", $_SESSION["auth_data"]["permissions"] ?? []) die("Acceso denegado"); } -$aulario_id = Sf($_GET["aulario"] ?? ""); -$centro_id = Sf($_SESSION["auth_data"]["entreaulas"]["centro"] ?? ""); -$alumno = Sf($_GET["alumno"] ?? ""); +function safe_id_segment($value) +{ + $value = basename((string)$value); + return preg_replace('/[^A-Za-z0-9_-]/', '', $value); +} + +function safe_centro_id($value) +{ + return preg_replace('/[^0-9]/', '', (string)$value); +} + +function path_is_within($real_base, $real_path) +{ + if ($real_base === false || $real_path === false) { + return false; + } + $base_prefix = rtrim($real_base, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; + 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"] ?? "")); if (empty($aulario_id) || empty($centro_id)) { require_once "_incl/pre-body.php"; @@ -24,9 +44,6 @@ if (empty($aulario_id) || empty($centro_id)) { exit; } -$aulario_id = basename($aulario_id); -$centro_id = basename($centro_id); - // Validate paths with realpath $base_path = "/DATA/entreaulas/Centros"; $real_base = realpath($base_path); @@ -50,11 +67,7 @@ $alumnos = []; // Resolve and validate alumnos path to ensure it stays within the allowed base directory $alumnos_real_path = realpath($alumnos_base_path); if ($alumnos_real_path !== false) { - // Ensure the resolved path is within the expected base path - $real_base_with_sep = rtrim($real_base, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; - $alumnos_real_with_sep = rtrim($alumnos_real_path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; - - if (strpos($alumnos_real_with_sep, $real_base_with_sep) === 0 && is_dir($alumnos_real_path)) { + if (path_is_within($real_base, $alumnos_real_path) && is_dir($alumnos_real_path)) { $alumnos = glob($alumnos_real_path . "/*", GLOB_ONLYDIR); usort($alumnos, function($a, $b) { return strcasecmp(basename($a), basename($b)); @@ -123,11 +136,24 @@ if (empty($alumno)) { } // If alumno is specified, validate and show their diary -$alumno = basename($alumno); $alumno_path = "$alumnos_base_path/$alumno"; +$real_alumnos_base = realpath($alumnos_base_path); +if (!path_is_within($real_base, $real_alumnos_base)) { + require_once "_incl/pre-body.php"; + ?> +
+

Diario del Alumno

+

Ruta de alumnos inválida.

+
+
@@ -138,6 +164,7 @@ if (!is_dir($alumno_path)) { require_once "_incl/post-body.php"; exit; } +$alumno_path = $real_alumno_path; // Get diario types and data $diario_types = [ @@ -223,11 +250,22 @@ require_once "_incl/pre-body.php"; format('Y-m-d') === $date; + } + if (!$is_valid_date || !array_key_exists($type, $diario_types)) { + $type = ""; + } +} + +if (!empty($type) && !empty($date)) { $type_file = "$alumno_path/Diario/$date/$type.json"; if (file_exists($type_file)): diff --git a/public_html/entreaulas/index.php b/public_html/entreaulas/index.php index ed3d551..31972ae 100755 --- a/public_html/entreaulas/index.php +++ b/public_html/entreaulas/index.php @@ -1,6 +1,28 @@ +require_once "_incl/pre-body.php"; + +function safe_id_segment($value) +{ + $value = basename((string)$value); + return preg_replace('/[^A-Za-z0-9_-]/', '', $value); +} + +function safe_centro_id($value) +{ + return preg_replace('/[^0-9]/', '', (string)$value); +} + +function safe_aulario_config_path($centro_id, $aulario_id) +{ + $centro = safe_centro_id($centro_id); + $aulario = safe_id_segment($aulario_id); + if ($centro === '' || $aulario === '') { + return null; + } + return "/DATA/entreaulas/Centros/$centro/Aularios/$aulario.json"; +} +?>

¡Hola, !

@@ -11,13 +33,26 @@ require_once "_incl/pre-body.php";?>
- ' . htmlspecialchars($aulario[ + $aulario_id = safe_id_segment($aulario_id); + if ($aulario_id === "") { + continue; + } + $aulario_path = safe_aulario_config_path($centro_id, $aulario_id); + if (!$aulario_path || !file_exists($aulario_path)) { + continue; + } + $aulario = json_decode(file_get_contents($aulario_path), true); + if (!is_array($aulario)) { + continue; + } + $aulario_name = $aulario["name"] ?? $aulario_id; + $aulario_icon = $aulario["icon"] ?? "/static/arasaac/aulario.png"; + echo ' + ' . htmlspecialchars($aulario_name) . ' Icono
- ' . htmlspecialchars($aulario["name"]) . ' + ' . htmlspecialchars($aulario_name) . '
'; } ?>
diff --git a/public_html/entreaulas/paneldiario.php b/public_html/entreaulas/paneldiario.php index 99f3e91..a6a1606 100755 --- a/public_html/entreaulas/paneldiario.php +++ b/public_html/entreaulas/paneldiario.php @@ -2,6 +2,25 @@ require_once "_incl/auth_redir.php"; require_once "_incl/tools.security.php"; ini_set("display_errors", "0"); + +function safe_id_segment($value) { + $value = basename((string)$value); + return preg_replace('/[^A-Za-z0-9_-]/', '', $value); +} + +function safe_centro_id($value) { + return preg_replace('/[^0-9]/', '', (string)$value); +} + +function safe_aulario_config_path($centro_id, $aulario_id) { + $centro = safe_centro_id($centro_id); + $aulario = safe_id_segment($aulario_id); + if ($centro === '' || $aulario === '') { + return null; + } + return "/DATA/entreaulas/Centros/$centro/Aularios/$aulario.json"; +} + // Funciones auxiliares para el diario function getDiarioPath($alumno, $centro_id, $aulario_id) { // Validate path components to avoid directory traversal or illegal characters @@ -85,11 +104,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_GET['api'])) { } } -switch ($_GET["form"]) { +$form_action = $_GET["form"] ?? ""; +switch ($form_action) { case "alumno_selected": - $alumno = $_GET["alumno"] ?? ""; - $centro_id = $_SESSION["auth_data"]["entreaulas"]["centro"] ?? ""; - $aulario_id = $_GET["aulario"] ?? ''; + $alumno = safe_id_segment($_GET["alumno"] ?? ""); + $centro_id = safe_centro_id($_SESSION["auth_data"]["entreaulas"]["centro"] ?? ""); + $aulario_id = safe_id_segment($_GET["aulario"] ?? ''); $photo_url = $_GET["photo"] ?? ''; if ($alumno !== "" && $centro_id !== "" && $aulario_id !== "") { $_SESSION["entreaulas_selected_alumno"] = $alumno; @@ -207,8 +227,8 @@ ini_set("display_errors", "0");