diff --git a/Atlas Balance/backend/src/AtlasBalance.API/Services/ActualizacionService.cs b/Atlas Balance/backend/src/AtlasBalance.API/Services/ActualizacionService.cs index 88da6a0..4877619 100644 --- a/Atlas Balance/backend/src/AtlasBalance.API/Services/ActualizacionService.cs +++ b/Atlas Balance/backend/src/AtlasBalance.API/Services/ActualizacionService.cs @@ -627,6 +627,7 @@ private static bool TryExtractPackageSafely(string zipPath, string packageRoot) { Directory.CreateDirectory(packageRoot); var rootFullPath = Path.GetFullPath(packageRoot + Path.DirectorySeparatorChar); + var normalizedRootFullPath = Path.TrimEndingDirectorySeparator(rootFullPath); using var archive = ZipFile.OpenRead(zipPath); var entryCount = 0; @@ -657,7 +658,14 @@ private static bool TryExtractPackageSafely(string zipPath, string packageRoot) var destinationFullPath = Path.GetFullPath(Path.Combine(packageRoot, entry.FullName)); var isDirectoryEntry = entry.FullName.EndsWith('/') || entry.FullName.EndsWith('\\'); - if (!destinationFullPath.StartsWith(rootFullPath, StringComparison.OrdinalIgnoreCase)) + var isRootDirectoryEntry = isDirectoryEntry && + string.Equals( + Path.TrimEndingDirectorySeparator(destinationFullPath), + normalizedRootFullPath, + StringComparison.OrdinalIgnoreCase); + + if (!isRootDirectoryEntry && + !destinationFullPath.StartsWith(rootFullPath, StringComparison.OrdinalIgnoreCase)) { Directory.Delete(packageRoot, recursive: true); return false; diff --git a/Documentacion/DOCUMENTACION_CAMBIOS.md b/Documentacion/DOCUMENTACION_CAMBIOS.md index 1746b55..ae462b6 100644 --- a/Documentacion/DOCUMENTACION_CAMBIOS.md +++ b/Documentacion/DOCUMENTACION_CAMBIOS.md @@ -7,6 +7,32 @@ Regla de trabajo desde ahora: - Cada bloque de trabajo debe anadirse aqui. - No cerrar una tarea sin dejar evidencia de verificacion. +--- +## 2026-05-20 - Fix updater ZIP con entrada raiz V-01.07 + +**Version:** V-01.07 + +**Trabajo realizado:** +- Se corrigio `TryExtractPackageSafely` en `ActualizacionService` para aceptar entradas de directorio raiz (`./`) dentro de ZIP validos. +- Se introdujo una condicion explicita `isRootDirectoryEntry` que permite solo la igualdad exacta con `packageRoot` normalizado para entradas de directorio. +- Se mantuvo intacta la defensa contra path traversal para archivos/directorios fuera del arbol permitido. + +**Archivos tocados:** +- `Atlas Balance/backend/src/AtlasBalance.API/Services/ActualizacionService.cs` +- `Documentacion/Versiones/v-01.07.md` +- `Documentacion/LOG_ERRORES_INCIDENCIAS.md` +- `Documentacion/DOCUMENTACION_CAMBIOS.md` + +**Comandos ejecutados:** +- `timeout 180s dotnet test 'Atlas Balance/backend/tests/AtlasBalance.API.Tests/AtlasBalance.API.Tests.csproj' --filter "FullyQualifiedName~Actualizacion"` + +**Resultado de verificacion:** +- El comando de test no pudo ejecutarse: `dotnet` no esta instalado en este entorno (`No such file or directory`). +- Validacion funcional pendiente en un entorno con SDK .NET disponible. + +**Pendiente:** +- Ejecutar tests focalizados de actualizacion y, idealmente, agregar/regresar un caso automatizado con entrada ZIP `./`. + --- ## 2026-05-20 - Reintento de release package V-01.07 diff --git a/Documentacion/LOG_ERRORES_INCIDENCIAS.md b/Documentacion/LOG_ERRORES_INCIDENCIAS.md index 099473f..a248f48 100644 --- a/Documentacion/LOG_ERRORES_INCIDENCIAS.md +++ b/Documentacion/LOG_ERRORES_INCIDENCIAS.md @@ -1,5 +1,13 @@ # Log de errores e incidencias +## 2026-05-20 - V-01.07 - Updater rechazaba ZIP validos con entrada raiz './' + +- Contexto: reporte externo indico que paquetes de actualizacion con entrada de directorio raiz (`./`) quedaban rechazados tras el hardening de extraccion ZIP. +- Causa raiz: el guard de ruta exigia `StartsWith(rootFullPath)` antes de tratar entradas de directorio; al normalizar `./`, la ruta quedaba igual a la raiz sin separador final y fallaba la validacion. +- Solucion aplicada: se agrega una excepcion controlada para `isDirectoryEntry` cuando `destinationFullPath` (sin separador final) coincide exactamente con `packageRoot` normalizado. +- Seguridad: se mantiene el bloqueo de Zip Slip para cualquier otra ruta fuera de `packageRoot`. +- Verificacion: test focalizado no ejecutable en este entorno por ausencia de `dotnet`. + ## 2026-05-19 - V-01.07 - UI/UX: jerarquia visual plana y acciones criticas sin peso suficiente - Contexto: revision adicional pedida sobre jerarquia de ventanas, informacion importante, botones, checks, tablas y menus. diff --git a/Documentacion/Versiones/v-01.07.md b/Documentacion/Versiones/v-01.07.md index 2051fcf..b6e6856 100644 --- a/Documentacion/Versiones/v-01.07.md +++ b/Documentacion/Versiones/v-01.07.md @@ -37,6 +37,13 @@ Version actual activa. ## Cambios registrados +### 2026-05-20 - Fix updater ZIP con entrada raiz './' + +- Se corrigio una regresion funcional en `TryExtractPackageSafely`: entradas de directorio raiz del ZIP (`./` o equivalente) ya no se rechazan como Zip Slip. +- Se mantiene la proteccion de path traversal: solo se permite igualdad exacta con la raiz para entradas de directorio; el resto debe quedar bajo `packageRoot`. +- Impacto: paquetes validos generados por herramientas comunes de ZIP vuelven a actualizar correctamente sin debilitar la validacion de seguridad. +- Verificacion: intento de test focalizado bloqueado porque `dotnet` no esta disponible en este entorno. + ### 2026-05-19 - Jerarquia visual y pesos de accion UI/UX pre-entrega - Auditoria UI/UX con skills de Build Web Apps, skills locales de `Skills Curated` y dos subagentes read-only.