InvoiceShelf lanzó un parche para la CVE-2026-55610, un fallo crítico que permitía a cualquier propietario de una empresa secuestrar cuentas de usuario de otra empresa. La vulnerabilidad, con una calificación de 8.7 en la escala CVSS, se debió a la falta de una comprobación del ámbito del tenant en el código Laravel de la aplicación.
Cómo funcionaba el fallo
InvoiceShelf es una herramienta SaaS desarrollada con Laravel que permite a las empresas gestionar usuarios, facturas y configuraciones desde un único panel de control. La plataforma lee un encabezado personalizado para identificar a un tenant. Cuando un Propietario (Owner) solicita el registro de un usuario, el código solo comprueba: "¿Es el solicitante un Propietario de su propia empresa?".
Nunca verifica que el usuario objetivo pertenezca al mismo tenant. El enlace implícito de modelo de ruta (route-model binding) de Laravel resuelve el ID de usuario a una fila en la tabla global de usuarios, y la política de autorización aprueba la solicitud basándose únicamente en el rol del solicitante.
Por lo tanto, un atacante podría:
- Proporcionar cualquier ID de usuario numérico en la URL de la solicitud.
- Recibir el registro completo del usuario, incluyendo el correo electrónico.
- Realizar una actualización que sobrescriba el correo electrónico y la contraseña de la víctima, e incluso reasigne la cuenta a la empresa del atacante como super-admin.
En la práctica, un Propietario malintencionado convirtió una herramienta de gestión empresarial en un arma universal de secuestro de cuentas. No se necesitaron privilegios más allá de "Owner".
Quiénes se ven afectados
Todos los clientes de InvoiceShelf que ejecutaran una versión anterior a la 2.4.1 estuvieron expuestos. Debido a que el fallo reside en la ruta principal de gestión de solicitudes, cualquier tenant podría ser el objetivo de cualquier otro Propietario, independientemente de su tamaño o postura de seguridad. El impacto incluye la pérdida de confidencialidad (direcciones de correo electrónico) y la pérdida de integridad (cambios de contraseña no autorizados, elevación a super-admin).
El parche
Los desarrolladores lanzaron la versión 2.4.1, añadiendo una comprobación explícita del tenant antes de cualquier operación de lectura o escritura en un registro de usuario. La corrección delimita el alcance de la consulta al identificador de la empresa activa, obligando a Laravel a devolver únicamente las filas que pertenecen al tenant del solicitante.
Lo que los desarrolladores deben aprender
- Nunca confíe en claves primarias globales en aplicaciones multi-tenant.
- Aplique un filtro de tenant a cada búsqueda en la base de datos, no solo a las acciones de eliminar o crear.
- Haga que las políticas de autorización validen tanto el rol del actor como la pertenencia al tenant del objeto objetivo.
- Trate las funciones implícitas del framework, como el
route-model binding, como conveniencias que pueden ocultar brechas de seguridad a menos que añada una delimitación de alcance explícita.
Mirando hacia el futuro
El incidente muestra un riesgo más amplio para cualquier SaaS que comparta tablas. Las auditorías de seguridad deben revisar todos los endpoints que acepten identificadores y confirmar que la delimitación de tenants se aplique de manera uniforme.
Conclusión: una sola comprobación de tenant omitida puede convertir un rol de usuario privilegiado en una puerta trasera universal. La delimitación de alcance adecuada no es opcional; es la base del aislamiento de datos en cualquier sistema multi-tenant.
