Fix: timing side-channel en login + validación de estado de autor/instancia en comentarios
Qué
Corrige dos hallazgos de la auditoría de backend (2026-08-27):
-
#5 (Medio) — timing side-channel en
AuthService.login(). -
#7 (Medio) — falta de validación de estado ACTIVO en
ComentarioNormalInstanciaService/ComentarioConfidencialInstanciaService.
Por qué
#5: cuando el email no existe, login() lanza la excepción antes de
llegar a authManager.authenticate() (que ejecuta BCrypt, deliberadamente
lento). Cuando el email sí existe, BCrypt corre igual. Esa diferencia de
tiempo permite a un atacante distinguir "email registrado" de "email no
registrado" sin necesidad de acertar ninguna contraseña — justo el tipo
de fuga que el resto del flujo de login se esfuerza en evitar (mismo
status/mensaje en todos los casos).
#7: ComentarioNormalEstudianteService/ComentarioConfidencialEstudianteService
ya validaban que el Estudiante y el Funcionario autor estuvieran
ACTIVO antes de crear un comentario. Sus pares de Instancia no lo
hacían — solo verificaban que ambos existieran. Esto permitía que un
funcionario desactivado (con JWT todavía vigente, ya que no hay
revocación activa de tokens) siguiera comentando instancias, y que se
comentara sobre una instancia inactiva.
Cambios
-
AuthService.java: constanteHASH_DUMMY_TIMING(hash BCrypt válido
de una contraseña que no corresponde a nadie) +passwordEncoder.matches()
dummy en la rama "email no existe" delogin(). -
ComentarioNormalInstanciaService.java/ComentarioConfidencialInstanciaService.java:
encrear(), se agregan las validacionesinstancia.getEstado() != ACTIVO
yautor.getEstado() != ACTIVO(422), mismo criterio y mensajes que ya
usan los servicios de comentarios de Estudiante.
Testing
- Nuevo test en
AuthServiceTest: verifica que el camino "email no
existe" llama apasswordEncoder.matches()(mitigación de timing) y
no llama aauthManager. - Nuevos tests en
ComentarioNormalInstanciaServiceTesty
ComentarioConfidencialInstanciaServiceTest: instancia no activa (422)
y autor no activo (422), sin persistir el comentario en ningún caso. - Suite completa: 521 tests, 0 failures, 0 errors (516 previos + 5 nuevos).