Modular Mango

Revisión de seguridad

Victorious English Academy — página y plataforma

victoriousenglishacademy.com · la app en …netlify.app · 25 de octubre de 2026 · revisión ligera

En resumen: la página de presentación está sana. La plataforma de alumnos está bien armada, pero su seguridad depende de un ajuste que hay que confirmar por dentro: las «reglas de acceso» de la base de datos (Supabase). Si están bien, el riesgo es bajo; si faltan, cualquiera podría leer o cambiar el progreso y los datos de otros alumnos. Eso es lo primero a revisar. Lo demás son mejoras de blindaje.

Cómo se hizo esta revisión

Solo miramos lo que cualquier visitante recibe al abrir la página: la portada, los archivos de diseño y de funciones, y la configuración que viaja con ellos. No se enviaron formularios, no se probaron claves ni usuarios, no se crearon cuentas y no se atacó el sitio de ninguna manera. Fue una mirada, no una prueba de intrusión.

Lo que está bien

Lo que conviene mejorar

Faltan «reglas de blindaje» del navegador Media

Son instrucciones que el sitio le da al navegador para protegerse de trucos conocidos (por ejemplo, que otra página lo meta dentro de la suya para engañar al visitante). Hoy no están puestas.

Cómo se arregla: agregar un archivo de configuración en Netlify con esas reglas. Es un cambio de una sola vez, sin tocar el diseño. Nosotros lo podemos dejar listo.

La protección de conexión no cubre los subdominios Baja

El sitio ya exige conexión segura, pero esa exigencia no se extiende a posibles direcciones «hijas» (como app.tusitio.com). Mientras no uses subdominios, casi no importa.

Cómo se arregla: añadir una palabra a esa misma regla de conexión segura.

El nombre del visitante viaja en el enlace de WhatsApp Baja

Cuando alguien usa el formulario, su nombre se arma dentro del enlace que abre WhatsApp. No es un fallo de seguridad, pero es un dato personal que queda en la dirección y pasa por un tercero.

Cómo se arregla: pedir el nombre solo cuando de verdad se necesite, o no incluirlo en el enlace.

No hay un correo para reportar problemas de seguridad Opcional

No es un fallo. Es una buena práctica: un archivo estándar con un correo de contacto, para que quien detecte algo sepa a quién avisar.

Cómo se arregla: publicar un pequeño archivo de contacto. Cinco minutos.

La plataforma de alumnos (la app)

La app guarda cuentas y progreso en Supabase, y habla con esa base de datos directamente desde el navegador de cada alumno. Eso es normal y moderno, pero significa que toda la protección de los datos vive en la configuración de Supabase, no en el código de la página.

Las «reglas de acceso» de la base (RLS) Revisar ya

La llave que viaja en la web es pública a propósito (así se diseñó), así que no es el problema. El problema aparece si las tablas de alumnos no tienen activada la «seguridad por fila»: en ese caso, cualquiera con esa llave podría leer o modificar el progreso y los datos de otros alumnos. No se pudo comprobar desde afuera sin meternos en datos de la gente, así que hay que verificarlo por dentro.

Cómo se verifica: en el panel de Supabase, confirmar que las tablas profiles, student_progress, quiz_attempts y onboarding_responses tengan RLS activo, con políticas que aten cada fila a su dueño (el usuario solo ve y edita lo suyo). El propio panel tiene un «Security Advisor» que lo marca.

El contenido se carga sin haber iniciado sesión Media

Las lecciones, el vocabulario y los retos están dentro del código de la página. El inicio de sesión es, por ahora, una cortina visual: quien abra la página puede ver el contenido sin cuenta. Importa solo si ese contenido es exclusivo de alumnos de pago.

Cómo se arregla: servir el contenido de alumnos desde la base protegida, no desde la página.

La sesión queda guardada en el navegador sin blindaje Media

La sesión del alumno se guarda en el navegador. Sin las «reglas de blindaje» (sobre todo la lista de orígenes de confianza, CSP), si se colara un script ajeno, podría robar esa sesión. Es el mismo arreglo que recomendamos para la página, y aquí pesa más porque hay cuentas.

Cómo se arregla: poner la CSP y sacar el código a archivos aparte para poder cerrarla bien.

Detalles de endurecimiento Bajas

La contraseña mínima es de 6 caracteres (mejor 8, con confirmación por correo y bloqueo de contraseñas filtradas, todo desde Supabase). La librería de Supabase se carga «a la última versión» sin fijar cuál, lo ideal es fijarla. Y faltan las mismas cabeceras de blindaje que la página.

Una mejora de fondo: mudar la plataforma a Cloudflare

Hoy el sitio vive en Netlify, que funciona bien para una página. Pero como esto va a ser una plataforma con usuarios y cuentas, vale la pena considerar mudarla a Cloudflare (Pages y Workers). Trae de fábrica protección contra ataques de saturación y bots, un cortafuegos de aplicaciones, y una red más robusta y con mejor costo a medida que crece. Es el mismo tipo de base sobre la que Modular Mango construye sus plataformas, así que te podemos acompañar en esa mudanza si tu amigo quiere.

Para pasarle a tu Claude Code

Si estás construyendo el sitio con Claude Code, puedes pegarle estas preguntas y pedirle que las resuelva. Van de lo más importante a lo opcional.

1. Base de datos: ¿tiene RLS? Lo primero

Si usas Supabase (o cualquier base de datos conectada desde el navegador), lo más urgente es confirmar que cada tabla tenga activada la «seguridad por fila» (RLS) con sus políticas. Sin eso, la llave pública que viaja en la web deja que cualquiera lea o borre toda la base.

Pídele a tu Claude: «Revisa si mis tablas de Supabase profiles, student_progress, quiz_attempts y onboarding_responses tienen RLS activado con políticas que aten cada fila a auth.uid(); muéstrame cuáles están abiertas y ayúdame a cerrarlas sin romper la app».

2. Reglas de blindaje del navegador

Pídele a tu Claude: «Crea un archivo _headers en el proyecto de Netlify con Content-Security-Policy (primero en modo solo-reporte), X-Content-Type-Options, X-Frame-Options, Referrer-Policy y Permissions-Policy, adaptado a mi sitio».

3. Llaves y secretos

Pídele a tu Claude: «Revisa que ninguna llave privada o secreto esté en el código del frontend; las que deban ser públicas, confírmame que lo sean; mueve el resto a variables de entorno».

4. Archivo de contacto de seguridad

Pídele a tu Claude: «Crea un /.well-known/security.txt con un correo de contacto».

Dato útil. El candado de seguridad (certificado) vence el 3 de diciembre de 2026. Netlify lo renueva solo, pero conviene darle un vistazo a mediados de noviembre para confirmar que la renovación quedó activa.
Alcance de esta revisión. Se miró la página principal y sus archivos públicos, sin tocar nada. Una revisión más profunda (configuración interna de Netlify, repositorio del sitio o pruebas activas con permiso) requiere accesos que aquí no se usaron. Si en algún momento el sitio empieza a guardar datos de alumnos o a cobrar, conviene repetir la revisión con ese alcance mayor.