Moscú UTC+3
Portada tipográfica en negro: «8 found. 8 fixed.» sobre cuatro hallazgos de la auditoría de tarasovvitalii.com, cada uno con su nivel de riesgo y una etiqueta lima «Fixed».

Revisamos desde dentro la seguridad de este portfolio: chat, API de mensajes, servidor y 15 demos conceptuales. Hallamos 8 fallos, entre ellos inyección de script en el origen del chat, y los corregimos todos.

Etiquetas
Interno Un producto propio de VITON13
Año
2026
Disciplinas
Seguridad, Webs
Estudio
by VITON13
Idiomas
inglés, ruso, español, chino

Contexto

Este sitio es más que páginas estáticas. Tiene un chat sobre VITON ID (Firebase Auth y Firestore), una pequeña API en Node que guarda los mensajes del formulario y envía correos, un servidor nginx en Docker y copias de 15 sitios conceptuales en /demos/. El 28 de septiembre de 2026 lo revisamos todo desde dentro: el código, las reglas de Firestore, la configuración del servidor y de los contenedores y las dependencias npm.

Para cada parte hicimos la pregunta de un atacante: qué puede hacer con ella alguien de fuera y cuánto le costaría al propietario. Un hallazgo solo contaba si lo reproducíamos, y cada corrección se volvió a probar en una copia local de la configuración de producción antes de publicarla.

  • 8

    hallazgos de seguridad, todos corregidos

    Fuente: Revisión de código, 28 sept. 2026

  • 1

    fallo de riesgo alto: inyección de script en el origen del chat, cerrado

    Fuente: Reproducido antes y después de la corrección en una copia local

  • 119

    páginas de demos cargadas con la nueva política de seguridad, 0 infracciones

    Fuente: Comprobación con Chrome headless, 28 sept. 2026

  • 0

    vulnerabilidades conocidas en las dependencias npm del sitio y la API

    Fuente: npm audit, 28 sept. 2026

Enfoque

Leímos cada ruta de la API, la verificación de tokens, las reglas de Firestore con sus 39 pruebas en el emulador, los archivos de nginx y Docker Compose y el código de las 15 demos. En lugar de atacar el servidor real, levantamos los mismos contenedores en local (nginx y la API con la configuración de producción) y probamos allí cada ataque.

El hallazgo más grave estaba en una demo, no en el propio sitio. El catálogo de Oriva insertaba el parámetro ?cat= de la dirección en la página como HTML, así que un enlace preparado ejecutaba script en tarasovvitalii.com, el origen donde el chat guarda su sesión de Firebase. Un clic del propietario habría bastado para entregar la bandeja de entrada. Las otras 14 demos solo comparan los parámetros con valores conocidos.

Correcciones: la demo solo acepta categorías y órdenes conocidos; /demos/ tiene su propia Content-Security-Policy; Leaflet está fijado con hashes de integridad; la redirección /demos/<id> se construye con un patrón estricto; se rechazan las direcciones que podían colar campos en enlaces mailto:; un límite diario global protege el almacenamiento; la API funciona con un usuario sin privilegios y un sistema de archivos de solo lectura; la versión de nginx está oculta y HSTS cubre www.

Resultados

8 hallazgos, 8 corregidos: 1 alto, 1 medio y 6 bajos. El código que se ejecutaba en la demo antigua no hace nada en la nueva, y la petición que antes inyectaba una cabecera Set-Cookie ahora recibe un 404 normal. Las 119 páginas de demos cargan con la nueva política sin ninguna infracción, las pruebas de la API pasan 48 de 48 con las nuevas reglas cubiertas y npm audit no encuentra vulnerabilidades conocidas en las dependencias del sitio y de la API.

Revisado y correcto: la verificación de tokens de Firebase (solo RS256, id de clave obligatorio, audiencia, emisor y caducidad comprobados), las reglas de Firestore (nadie lee conversaciones ajenas ni escribe como el propietario), las plantillas de correo (todos los valores escapados, sin inyección de cabeceras), los registros (sin tokens, correos ni IP) y la interfaz del chat (el texto del visitante nunca se inserta como HTML).

Auditoría de seguridad

Cada hallazgo se reprodujo antes de contarlo y se volvió a probar tras la corrección, en una copia local de los contenedores de producción. Ordenados por riesgo.

Revisado el 28 sept 2026 · hallazgos: 8 · corregidos: 8

  1. Alto

    Inyección de script en una demo, en el origen del chat

    Corregido

    Antes

    El catálogo de Oriva insertaba el parámetro ?cat= en la página como HTML. Un enlace preparado ejecutaba script en tarasovvitalii.com, donde el chat guarda su sesión de Firebase: un clic del propietario podía exponer la bandeja de entrada y su cuenta.

    Después

    Solo se aceptan categorías y órdenes conocidos. El mismo código ya no se ejecuta, y las otras 14 demos se revisaron en busca del mismo patrón.

  2. Medio

    Demos sin política de seguridad y script externo sin control de integridad

    Corregido

    Antes

    52 páginas de demos cargaban Leaflet desde unpkg.com sin hash de integridad, y /demos/ no enviaba Content-Security-Policy: un CDN comprometido o cualquier script inyectado llegaba a todo el origen.

    Después

    Leaflet está fijado con hashes SRI y /demos/ tiene su propia política: peticiones solo al propio sitio, scripts solo del sitio y del archivo fijado, sin plugins. 119 páginas, 0 infracciones.

  3. Bajo

    Inyección de cabeceras en una redirección del servidor

    Corregido

    Antes

    La redirección de /demos/<id> a /demos/<id>/ devolvía la ruta decodificada tal cual, así que %0d%0a en un enlace escribía una cabecera extra en la respuesta, por ejemplo Set-Cookie.

    Después

    La redirección solo acepta letras, dígitos, guiones y guiones bajos y construye la dirección por sí misma. La misma petición recibe ahora un 404 normal.

  4. Bajo

    Campos ocultos en los enlaces «Responder» del propietario

    Corregido

    Antes

    Una dirección como me@x.com?bcc=…&body=… pasaba la validación, y el enlace Responder de la bandeja y de los correos rellenaba una copia oculta y un texto. Los nombres también podían llevar caracteres de cambio de dirección que disfrazan el texto.

    Después

    Se rechazan las direcciones con delimitadores de URL, se codifican en los enlaces mailto: y se eliminan los caracteres de cambio de dirección. Nuevas pruebas de la API cubren los tres casos.

  5. Bajo

    Sin límite global para los mensajes guardados

    Corregido

    Antes

    Los límites eran solo por dirección IP. Cambiando de dirección se podían seguir añadiendo envíos del formulario y de bots hasta llenar el disco.

    Después

    Un límite diario global de envíos guardados (500 por defecto) se suma a los límites por IP. Superado, el formulario responde «inténtalo más tarde».

  6. Bajo

    La API de mensajes se ejecutaba como root

    Corregido

    Antes

    El contenedor de la API funcionaba como root, con un sistema de archivos escribible y todas las capacidades de Linux por defecto: cualquier fallo daría a un atacante un punto de apoyo cómodo.

    Después

    Funciona con el usuario sin privilegios node, sobre un sistema de archivos de solo lectura, sin capacidades de Linux y sin escalada de privilegios.

  7. Bajo

    Versión del servidor visible y rama de nginx obsoleta

    Corregido

    Antes

    Cada respuesta llevaba «server: nginx/1.27.5», y el contenedor del sitio usaba la rama 1.27, que ya no recibe correcciones.

    Después

    La versión está oculta en todas las respuestas y el contenedor usa la rama estable actual de nginx.

  8. Bajo

    HTTPS obligatorio sin cubrir www

    Corregido

    Antes

    La cabecera HSTS, que indica al navegador usar solo HTTPS, se enviaba en el dominio principal pero no en www, y no cubría subdominios.

    Después

    www también envía HSTS y la política incluye los subdominios, así que http://www… también pasa a HTTPS.

Lo que esto no demuestra

Es nuestro propio sitio, no un trabajo para un cliente. La revisión la hicimos nosotros a partir del código fuente; no es una prueba de penetración independiente ni un certificado. Reprodujimos los ataques en una copia local de los contenedores de producción, no contra el servidor real.

El resultado cubre lo revisado el 28 de septiembre de 2026: el código, las dependencias o las demos nuevas necesitan la misma revisión. Las demos siguen compartiendo el origen del sitio. La nueva política limita lo que podría alcanzar un código inyectado; llevar las demos a su propio dominio las aislaría por completo.

¿Planeas algo parecido? Nuestro fundador, Tarasov Vitalii, lee cada mensaje personalmente.

Todos los trabajos

Siguiente proyecto

Möbius School & InstituteWeb de colegio y universidad con área personal Concepto2026 Todos los trabajos (32)