diff --git a/api/lab/descargar_orden.php b/api/lab/descargar_orden.php index afba180..d166b51 100644 --- a/api/lab/descargar_orden.php +++ b/api/lab/descargar_orden.php @@ -1,29 +1,43 @@ 'Archivo inválido']); exit; } -// Solo archivos con prefijo de orden (seguridad adicional) -if (!preg_match('/^orden_[a-zA-Z0-9_]+\.[a-zA-Z0-9]+$/', $filename)) { - http_response_code(403); - echo json_encode(['error' => 'Acceso denegado']); - exit; +$projectRoot = realpath(__DIR__ . '/../../'); +$uploadsBase = realpath($projectRoot . '/uploads'); + +// Resolver la ruta completa: +// - Si ya empieza con uploads/ → resolver desde raíz del proyecto +// - Si es solo un nombre de archivo → buscar en uploads/media/ +if (preg_match('#^uploads/#', $fileParam)) { + $path = realpath($projectRoot . '/' . $fileParam); +} else { + // Solo nombre: solo aceptar alfanumérico + guiones/puntos, sin slashes + if (!preg_match('/^[a-zA-Z0-9_\-\.]+$/', $fileParam)) { + http_response_code(400); + echo json_encode(['error' => 'Archivo inválido']); + exit; + } + $path = realpath($projectRoot . '/uploads/media/' . $fileParam); } -$path = realpath(__DIR__ . '/../../uploads/media/' . $filename); -$base = realpath(__DIR__ . '/../../uploads/media'); +$base = $uploadsBase; // Verificar que el archivo esté dentro del directorio permitido if (!$path || !$base || strpos($path, $base) !== 0 || !is_file($path)) { @@ -38,7 +52,7 @@ $mime = finfo_file($finfo, $path); finfo_close($finfo); // Mapa de extensiones como fallback -$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); +$ext = strtolower(pathinfo($fileParam, PATHINFO_EXTENSION)); $mimeMap = [ 'pdf' => 'application/pdf', 'doc' => 'application/msword', @@ -69,7 +83,10 @@ $mimeToExt = [ 'image/webp' => 'webp', ]; $downloadExt = ($ext === 'bin' && isset($mimeToExt[$mime])) ? $mimeToExt[$mime] : $ext; -$downloadName = substr($filename, 0, strrpos($filename, '.') + 1) . $downloadExt; +$downloadName = basename($fileParam); +if ($ext === 'bin' && isset($mimeToExt[$mime])) { + $downloadName = substr($downloadName, 0, strrpos($downloadName, '.') + 1) . $downloadExt; +} header('Content-Type: ' . $mime); header('Content-Disposition: ' . $disposition . '; filename="' . rawurlencode($downloadName) . '"');