# Verificación de las correcciones de seguridad
## Plataforma Kynda

**Fecha:** 21 de agosto de 2026
**Objeto:** comprobar si los problemas detectados en la auditoría de agosto están resueltos, y revisar el código escrito para resolverlos.
**Material revisado:** 829 líneas de instrucciones de base de datos repartidas en cinco actualizaciones, 2.584 líneas del nuevo panel interno y 574 líneas de pruebas automáticas.
**Método:** tres revisiones independientes en paralelo. Cada problema de severidad crítica o alta se confirmó después mediante lectura directa del código.

---

## 1. Resumen

Los ocho problemas de la auditoría de agosto están corregidos. El equipo sustituyó las 22 políticas de acceso a datos una por una, revocó más permisos de los que se habían recomendado y detectó por su cuenta un fallo adicional que la auditoría original no había identificado.

La corrección, sin embargo, introdujo un problema nuevo. En el estado actual, el administrador de cualquier empresa cliente puede concederse el rol de operaciones de Kynda y acceder con él a los datos del resto de clientes. Se trata de un fallo del mismo tipo que el que acababa de cerrarse: un permiso que no queda limitado a la empresa que lo concede.

Existe además una segunda cuestión, menos visible pero de consecuencias parecidas. Las pruebas automáticas que se escribieron para impedir que estos fallos reaparezcan no verifican lo que aparentan verificar.

Por último, una copia de seguridad completa realizada el 9 de septiembre ha permitido confirmar en los datos un defecto que la auditoría de agosto había anticipado: existen ficheros almacenados sin registro en la base de datos, invisibles para el proceso de purga por retención.

| Indicador | Antes | Ahora |
|---|---|---|
| Problemas de la auditoría de agosto sin resolver | 8 | 0 |
| Vulnerabilidades introducidas por la corrección | no aplica | 2 críticas y 3 altas |
| Pruebas que verifican realmente las políticas de acceso | no aplica | 3 de 11 |

---

## 2. Problemas corregidos

Cada uno se comprobó contra el código.

| Problema de la auditoría de agosto | Solución aplicada |
|---|---|
| Las funciones de validación no comprobaban el rol de quien las invocaba | Se añadió la comprobación como primera instrucción en las once funciones del panel. De paso se cerró un fallo secundario que permitía averiguar si una evidencia existía |
| Un participante podía marcar su propia evidencia como aprobada | Las políticas limitan ahora qué estados puede escribir el propietario de un registro. El estado "aprobada" ya no está entre ellos |
| El alta de usuario permitía asignarse a una empresa ajena | Una función nueva valida el alta contra tres fuentes legítimas, y exige además que la empresa esté activa y sea de tipo cliente |
| El registro de auditoría admitía entradas falsificadas | Se revocó el permiso de escritura y la política quedó restringida al proceso del servidor |
| La empresa activa se deducía de datos que el propio usuario controlaba | Ahora se lee únicamente de datos que solo el servidor puede escribir |
| Los indicadores de impacto se truncaban en silencio | Las consultas filtran por campaña en la base de datos y recorren los resultados por páginas. Se pasó de un uso de paginación a nueve |
| La subida de evidencias no comprobaba la pertenencia del usuario | Se añadió la comprobación de ámbito |
| El escaneo de un código QR reactivaba accesos previamente revocados | La operación devuelve ahora un error en lugar de restaurar la membresía |

Dos aspectos merecen mención aparte, porque superan lo que se había recomendado.

En primer lugar, la revocación de permisos de escritura alcanzó no solo al rol anónimo sino también al autenticado, sobre todas las tablas de la base de datos. La auditoría de agosto daba ese problema por resuelto parcialmente; con este cambio queda cerrado por completo.

En segundo lugar, el equipo identificó por su cuenta una suplantación de identidad de empresa que se producía en cinco rutas concretas de la aplicación, aquellas cuyo nombre contiene un punto y que por ese motivo quedaban fuera del filtro de seguridad general. El fallo está corregido y documentado en el propio código.

---

## 3. Problemas introducidos por la corrección

### 3.1 Un administrador de empresa puede obtener acceso de operaciones

**Severidad: crítica.**

La secuencia se verificó paso a paso y funciona en el código actual.

1. La función que asigna roles a un usuario declara que solo admite dos valores, "usuario" y "administrador de empresa". Esa declaración, sin embargo, existe únicamente en el código fuente y desaparece al compilar; en ejecución no hay ninguna validación. Como la función es accesible por red, cualquiera puede invocarla con un valor distinto.
2. La función que traduce el nombre del rol a su identificador interno acepta cualquier texto y lo busca en la tabla de roles. El rol de operaciones figura en esa tabla, con alcance global.
3. La asignación se aplica sobre la propia empresa del atacante, de modo que la comprobación de pertenencia no la bloquea.
4. Al concluir, el sistema actualiza la credencial del usuario afectado con el rol recién asignado.
5. La comprobación de personal interno consulta esa credencial sin verificar a qué empresa corresponde el rol. Pasa a ser válida en todas, y con ella se abren las políticas de acceso de unas cuarenta tablas.
6. El control de entrada al panel interno busca una membresía con rol de plataforma, pero tampoco comprueba de qué empresa procede. Concede el acceso.
7. En la base de datos no existe ninguna restricción que impida asociar un rol de alcance global a una empresa cliente.

El sistema incorpora una protección que impide a un usuario modificar su propio rol. Resulta insuficiente, ya que basta con emplear una segunda cuenta; el propio código documenta ese vector como conocido en otro apartado.

El cierre requiere tres medidas simultáneas: validar el rol en ejecución, exigir que la membresía de personal interno pertenezca a la empresa de sistema, y añadir una restricción en la base de datos que rechace roles globales sobre empresas cliente.

### 3.2 Un operador puede revocar el acceso de un superadministrador

**Severidad: alta.**

De las cinco funciones que gestionan empresas en el panel, cuatro restringen su alcance a las de tipo cliente. Una no lo hace. El identificador de la empresa interna de Kynda, además, figura como constante visible en el repositorio.

Con ambos elementos, un operador puede revocar la membresía de cualquier compañero, incluido un superadministrador. La sesión de la persona afectada se invalida de inmediato, dado que la propia función se encarga de actualizar su credencial.

### 3.3 El ataque original permanece activo en parte

**Severidad: alta.**

La función que valida el alta de usuarios admite tres vías: invitación pendiente, lista de correos autorizados y portal de acceso público. Las dos primeras se comprobaron y no son falsificables.

La tercera sí lo es. La columna que determina el modo de alta tiene valor predeterminado "público", de manera que toda empresa creada antes del panel nuevo lo mantiene salvo modificación manual. Un administrador de empresa puede además restablecerlo cuando lo desee.

Contra esas empresas, el registro utilizando el identificador de otra sigue concediendo membresía activa sin haber accedido nunca a su portal. El rol obtenido es de usuario, no de administrador, pero permite consultar sus campañas y sus acciones.

### 3.4 Existe una cuenta de operaciones de pruebas en el entorno productivo

**Severidad: alta.**

La actualización que crea las cuentas de personal interno incluye una dirección destinada a pruebas, acompañada de un comentario que indica que solo la emplean los entornos no productivos. La actualización, no obstante, se ejecuta en todos ellos.

Quien se registre con esa dirección obtiene el rol de operaciones con alcance global. El dominio pertenece a un espacio de nombres reservado, por lo que la cuenta resulta inalcanzable siempre que la confirmación de correo esté activada. La configuración incluida en el repositorio la tiene desactivada, con una nota que indica activarla en producción, y el script de configuración automática no gestiona ese ajuste en los proyectos alojados.

La seguridad de una cuenta con acceso a todos los clientes depende, por tanto, de una opción de panel que el repositorio ni controla ni verifica. Conviene comprobarlo de forma inmediata.

### 3.5 Una función que no verifica quién la invoca

**Severidad: media.**

En el esquema interno de la base de datos existe una función con privilegios elevados que concede membresías de personal a cualquier identificador de usuario que reciba, sin comprobación alguna sobre quien la ejecuta.

Lo único que impide su explotación es que ese esquema no esté publicado en la interfaz de la base de datos, lo cual constituye de nuevo un ajuste de panel y no una medida en código. El endurecimiento de permisos, además, se aplicó únicamente al esquema público, de modo que las funciones nuevas del esquema interno continúan naciendo con permisos concedidos.

---

## 4. Un defecto documentado en agosto, confirmado ahora en los datos

La auditoría de agosto advirtió que el proceso de subida de evidencias no comprueba el resultado de la inserción en la tabla de ficheros multimedia. La consecuencia prevista era que una fotografía pudiera quedar almacenada sin su registro correspondiente en la base de datos.

Una copia de seguridad completa de ambos entornos, realizada el 9 de septiembre, ha permitido comprobar si eso llegó a ocurrir. El método consistió en contrastar cada ruta registrada en la base de datos con los ficheros efectivamente presentes en el almacenamiento.

| Entorno | Registradas | Descargadas | Faltantes | Sin registro |
|---|---|---|---|---|
| Producción | 55 | 55 | 0 | 0 |
| Validación | 3 | 3 | 0 | 11 |

En producción los recuentos coinciden con exactitud: las cincuenta y cinco fotografías registradas están presentes, y no existe ninguna adicional. En validación, en cambio, se localizaron once ficheros que carecen de registro en la base de datos. Siguen además una estructura de carpetas distinta de la documentada, y su contenido corresponde a pruebas automatizadas.

La relevancia no reside en el número sino en el mecanismo. El proceso de purga por retención opera sobre la tabla de ficheros multimedia. Un fichero que no figure en ella resulta invisible para ese proceso y, en consecuencia, no se elimina nunca, con independencia del plazo de retención que se haya configurado.

En producción el problema no se ha materializado hasta la fecha. El mecanismo que lo permite, sin embargo, es idéntico en ambos entornos, y allí los ficheros afectados serían fotografías de personas identificables que el proceso de purga no alcanzaría. Ello incide directamente sobre la política de retención exigida y sobre el principio de limitación del plazo de conservación.

La corrección es acotada: comprobar el resultado de la inserción y registrar su fallo. Conviene además ejecutar de forma periódica el contraste entre almacenamiento y base de datos, que es una consulta de coste reducido y detecta el problema con independencia de su origen.

---

## 5. Las pruebas automáticas ofrecen una confianza que no está respaldada

Se añadieron cuatro conjuntos de pruebas de regresión y el total pasó de 57 a 93. El planteamiento es correcto; el resultado, en su mayor parte, no verifica lo que aparenta.

La causa resulta difícil de detectar. Al revocarse los permisos de escritura al rol autenticado, los ataques que las pruebas simulan fallan con un error de permisos antes de que la base de datos llegue a evaluar ninguna política de acceso. Y ninguna prueba comprueba el código de error devuelto: la búsqueda arroja cero coincidencias en todo el conjunto.

La consecuencia práctica es que las 22 políticas reescritas, que constituyen la corrección principal del informe, podrían revertirse por completo y solo fallaría una de las once pruebas de escritura.

Los hallazgos concretos son los siguientes. Existe una comprobación tautológica en el conjunto dedicado a la auto-aprobación, construida de forma que se cumple si hay error y no llega a ejecutarse si no lo hay, por lo que no verifica nada en ningún caso. El conjunto dedicado al canje de invitaciones reimplementa dentro de la propia prueba la consulta que debería estar verificando de la aplicación, de manera que un fallo introducido en la aplicación pasaría inadvertido. Y dos de los vectores identificados carecen por completo de cobertura: el registro con identificador de empresa ajena, que el propio equipo verificó contra el entorno de validación, y la suplantación mediante cabecera.

Solo tres pruebas verifican algo real: la de resolución de dominios, que opera sobre una función sin dependencias externas y está bien construida; una de lectura de membresías; y una tercera que declara explícitamente que su objeto es la revocación de permisos, que es en efecto lo que comprueba.

La preocupación no se refiere al estado actual sino al futuro. Si una actualización posterior volviera a conceder permisos de forma predeterminada, situación que ya se produjo en junio a raíz de un incidente real, las políticas quedarían como única defensa y nadie advertiría que están rotas.

---

## 6. Actuaciones recomendadas

Con carácter inmediato, y antes de cualquier otra intervención:

1. Validar el rol en ejecución durante su asignación, restringir el control de acceso al panel a la empresa de sistema y añadir la restricción correspondiente en la base de datos.
2. Incorporar el filtro de empresa cliente a la gestión de administradores y protegerla frente a la automodificación.
3. Retirar la cuenta de pruebas del conjunto de datos que se ejecuta en producción, y verificar hoy mismo si la confirmación de correo está activada en el proyecto productivo.
4. Establecer el modo de alta restringido en las empresas existentes y modificar el valor predeterminado de la columna.
5. Comprobar el resultado de la inserción en la tabla de ficheros multimedia durante la subida de evidencias, y programar el contraste periódico entre almacenamiento y base de datos.

A continuación:

5. Comprobar el código de error en cada prueba de ataque, y habilitar un rol de pruebas con permisos de escritura para que las políticas se evalúen realmente.
6. Cubrir los dos vectores que carecen de pruebas.
7. Revocar los permisos de ejecución también en el esquema interno, concediendo únicamente los estrictamente necesarios.
8. Trasladar la comprobación de personal interno a lectura de tabla, tal como ya se hizo con el rol de empresa.

---

## 7. Consideraciones sobre la interpretación de este informe

El equipo recibió una auditoría de seguridad y respondió reescribiendo por completo la capa de permisos. Documentó cada decisión, verificó los cambios contra un entorno real y añadió pruebas de regresión. Es una respuesta más completa que la habitual en circunstancias semejantes.

Lo ocurrido responde a un patrón conocido en cualquier reescritura extensa de permisos ejecutada en pocas semanas. Se cierra el problema que se tiene delante y se abre otro en la costura recién creada, que pasa inadvertido precisamente porque quien lo introduce lleva días trabajando sobre esa misma superficie. Las pruebas, escritas por la misma persona que realizó la corrección, heredaron el mismo punto ciego.

De ahí que las correcciones de seguridad requieran revisión por parte de alguien ajeno a su desarrollo. No es una cuestión de desconfianza, sino del modo en que opera la atención sostenida sobre un mismo problema.

---

*Los problemas de severidad crítica y alta recogidos en este informe se verificaron mediante lectura directa del código fuente.*
