Seguridad

Nuestro modelo de seguridad en una frase: no hay nada en un servidor que atacar. Todo lo que aparece a continuación es verificable desde tus DevTools.

Arquitectura

El generador es una aplicación de página única estática servida desde Cloudflare Pages: sin cuentas de usuario, sin autenticación y sin ningún código de backend en el flujo de generación. Cada operación de generación, codificación, escaneo y renderizado de QR se ejecuta completamente dentro de tu navegador. Un pequeño endpoint sin servidor lo acompaña y se enumera aquí en lugar de ocultarlo: /api/contact (el formulario de contacto, que guarda lo que envías en Cloudflare D1 y nos lo envía por correo). No se llama mientras generas un código QR; el comprobador de seguridad de URL es un producto aparte en check.qr.abundera.ai. Comprobar si un código QR es seguro

Modelo de amenaza

Dado que el generador no recopila, almacena ni transmite datos de usuario (los dos endpoints anteriores solo gestionan lo que envías explícitamente), las amenazas más comunes en aplicaciones web — robo de credenciales, brecha de base de datos, secuestro de sesión, inyección del lado del servidor — no se aplican a él. La superficie de ataque restante es el paquete de activos estáticos (HTML, CSS, JavaScript) servido desde nuestro origen. Diseñamos asumiendo:

Política de Seguridad de Contenido — por directiva

La política que aparece a continuación se lee del archivo _headers desplegado en el momento de compilar esta página, así que no puede desincronizarse de lo que envía el edge. Verifícala en los encabezados de respuesta de cualquier solicitud.

Content-Security-Policy:
  default-src 'self';
  script-src 'self' https://abundera.ai 'wasm-unsafe-eval' https://challenges.cloudflare.com;
  worker-src 'self' blob:;
  style-src 'self' 'unsafe-inline' https://abundera.ai;
  font-src 'self';
  img-src 'self' data: blob: https:;
  connect-src 'self' https: https://challenges.cloudflare.com;
  frame-src 'self' https://challenges.cloudflare.com;
  frame-ancestors 'none';
  base-uri 'self';
  form-action 'self'

Qué permite cada directiva y dónde implica concesiones:

Lo que CSP no puede hacer

CSP limita desde dónde cargará código el navegador. No verifica qué hace el código cargado. Si nuestro origen se viera comprometido, el primer punto del modelo de amenaza, el script del atacante se ejecutaría con los mismos permisos que el nuestro, incluidas las concesiones de connect-src e img-src anteriores. Nuestras defensas frente a eso están por delante de CSP: los despliegues salen a través de una única cuenta de Cloudflare con tokens con alcance limitado, los nombres de archivo de los activos llevan un hash de contenido para que un archivo sustituido cambie cada URL que lo referencia, y el service worker solo almacena en caché respuestas GET del mismo origen. El manifiesto describe el sitio tal como se publica. No es una afirmación de que ninguna página web pueda enviar datos a ningún sitio jamás, y preferimos que nos exijas cumplir la declaración más estrecha y verificable.

Se aplican diferentes políticas CSP a /bio/* (relajación de img-src para avatares suministrados por el usuario) y /embed/* (relajación de frame-ancestors para incrustación intencional). Ambas están documentadas en site/_headers.

Encabezados de transporte y marcos

Service worker

Nuestro service worker (site/sw.js) almacena en caché solo activos del mismo origen. El controlador de fetch rechaza explícitamente las solicitudes de origen cruzado y los métodos que no son GET — puedes leer la lógica en /sw.js (el código se publica sin minificar lo suficiente como para seguirlo). Las escrituras en caché están envueltas en event.waitUntil() para que no puedan descartarse en medio de una navegación.

Sanitización de entradas

Cada ruta de renderizado que acepta entrada de usuario la trata como texto no confiable:

Obtención de imágenes de origen cruzado

Cuando un usuario pega una URL https: como foto de vCard o logotipo, el navegador la obtiene sujeto a CORS y la lista de permitidos img-src de nuestro CSP. La imagen se renderiza en un canvas. Nunca se convierte en DOM activo, nunca se ejecuta como código y nunca llega a nuestro origen — la obtención es navegador → imagen remota, y el resultado se pinta en el lado del cliente. Un atacante que controla una URL de imagen remota puede rastrear que la URL fue cargada (una línea de registro en su propio servidor), pero no puede filtrar nada de nuestra página.

Integridad de Subrecursos (SRI)

Todo el JavaScript y CSS que enviamos es del mismo origen. No cargamos scripts ni hojas de estilo de terceros, por lo que los hashes SRI no son aplicables. Si alguna vez cargamos un activo de terceros, incluiremos un atributo integrity SRI en él y documentaremos el proceso de actualización de hash en esta página.

Reportar una vulnerabilidad

Si descubres un problema de seguridad que afecta a Abundera QR — ya sea en nuestro código, nuestro despliegue o en una dependencia que enviamos — por favor repórtalo de forma privada a security@abundera.ai. Nuestro objetivo es triagiar en 72 horas. También puedes contactarnos a través de los detalles de contacto en nuestro archivo /.well-known/security.txt.

Sin programa de recompensas (por ahora)

Actualmente no ofrecemos recompensas pagadas, pero cada informe válido confirmado recibe crédito en el registro de cambios y nuestro agradecimiento público.

Verifica cualquiera de lo anterior

Cada afirmación en esta página es verificable desde los DevTools de tu navegador sin necesidad de confiarnos:

Contacto

Divulgaciones de seguridad: security@abundera.ai

Última actualización: 2026-09-03. Próxima revisión: 2026-12-03.