Si encuentras una vulnerabilidad, no la publiques en un issue ni en un canal abierto. Avisa en privado al equipo de VANTS.
Capas de defensa
Identidad y sesiones
El inicio de sesión lo gestiona Auth0, así que VANTS no guarda contraseñas. Las rutas que actúan en nombre de un usuario piden la cabeceraAuthorization: Bearer <token de acceso> y el servidor valida el token antes de responder. Las lecturas públicas, como torneos, equipos o artículos, no necesitan sesión.
Trata los tokens como credenciales: no los pegues en issues, registros ni capturas de pantalla.
Datos
La base de datos vive en Neon y tiene dos caminos de acceso:- Lectura pública. Una función de solo lectura expone únicamente las tablas de una lista permitida. Quita de las respuestas las columnas de identidad, como el correo, parametriza los valores, limita el número de filas y el uso por IP, y no devuelve los errores internos de la base de datos. Una tabla nueva no se puede leer por este camino hasta que se añade a la lista de forma explícita.
- Escrituras de usuario. Las que se hacen desde la web usan el token de Auth0 del propio usuario.
La web y la API
El Worker de Cloudflare atiende todas las peticiones antes de servir la web o la API.Cabeceras de seguridad
El Worker añade estas cabeceras a las páginas y a las respuestas de la API:Origen, bots y límites
- Origen. Las rutas de la API que usa la web comprueban la cabecera
Origin. Una petición de un navegador que llega desde un dominio ajeno a VANTS recibe403, y las solicitudes previas (preflight) solo se aprueban para dominios de VANTS. Es una protección para navegadores, no una autenticación: las peticiones sinOrigin(curl, scripts, servidores) se aceptan, por eso las rutas con datos de usuario exigen además un token. - Bots y escáneres. Se rechazan las peticiones sin
User-Agento con uno bloqueado, y las rutas típicas de escáneres. Los rastreadores legítimos de buscadores siguen pasando. - Límite de uso. Hay un límite de peticiones por IP. Al superarlo recibes
429conRetry-After. Cada instancia del Worker lleva su propia cuenta, así que es una defensa contra inundaciones y no una cuota exacta. - Métodos y tamaño. El Worker solo acepta los métodos que usa la plataforma (
405para el resto) y limita el tamaño del cuerpo de cada ruta.
Webhooks
Un webhook es una entrada pública por naturaleza. Por eso cada evento se verifica antes de procesarlo, y uno con firma o secreto inválido se rechaza.Secretos
Los secretos no viven en el código. Cada uno se guarda en el sistema del servicio que lo usa:
Los archivos
.env.example son plantillas y no deben contener valores reales. Cópialos a .env en tu equipo y no subas nunca el .env: el .gitignore de Vantsgames ya lo excluye, igual que las claves .pem y .key.
Rotar un secreto
1
Genera una credencial nueva
Hazlo en el servicio de origen: Cloudflare, Neon, Discord, FACEIT, Stripe u otro.
2
Actualízala donde se usa
Para el Worker, ejecuta
npx wrangler secret put <NOMBRE>. Para los workflows, cambia el secreto en Settings → Secrets and variables → Actions del repositorio. Para el bot, cambia su variable de entorno. Si el mismo secreto existe en varios sitios, cámbialo en todos: el despliegue del Worker copia a Cloudflare algunos secretos del repositorio y sobrescribiría el valor nuevo con uno antiguo.3
Aplica el valor nuevo
Reinicia o vuelve a desplegar el servicio si hace falta para que tome el valor nuevo.
4
Revoca la credencial anterior
Hazlo en el servicio de origen y revisa sus registros por si alguien la usó.
Bot de Discord
Los comandos se agrupan en tres niveles: todos los miembros, staff y administrador. Bot de Discord los lista comando por comando.- El staff se reconoce por el nombre del rol. Crea esos roles solo para personas de confianza y limita quién puede gestionar roles en el servidor.
/setupsolo lo ejecutan administradores./agenteactúa sobre la plataforma. Restringe su uso a personas de confianza en Ajustes del servidor → Integraciones.- Concede al bot solo los permisos que necesita.
- Guarda el token del bot fuera del código y rótalo si se filtra.
Despliegues y CI
Los workflows viven en.github/workflows/ de Vantsgames. Estos son los que tocan producción:
Otros workflows programados vigilan el servicio, ejecutan el agente y sincronizan datos de FACEIT.
- Todos los workflows declaran permisos mínimos: son de solo lectura, salvo el de migraciones, que necesita escribir en el repositorio.
- Los despliegues y las migraciones comparten una cola: se ejecutan de uno en uno y no se cancelan a medias.
Antes de fusionar a
main, comprueba que tests esté en verde: el despliegue del Worker es un workflow aparte y no espera a las pruebas.git revert <sha> y haz push a main: el CI vuelve a desplegar. Revertir el archivo de una migración no deshace lo que ya aplicó en la base de datos: escribe una migración nueva que lo corrija.
Buenas prácticas para contribuir
- No subas secretos, tokens, archivos
.env, claves ni identificadores privados. Usa las plantillas.env.example. - No pegues tokens de acceso, cadenas de conexión ni capturas con credenciales en issues, pull requests o chats.
- En una ruta nueva que modifique datos, valida el token y comprueba que el usuario puede cambiar ese recurso.
- Valida las entradas y limita su tamaño. No devuelvas al cliente errores internos ni detalles del servicio de origen.
- Si una tabla nueva contiene datos personales, no la hagas legible por la API pública.
- En los workflows, declara permisos mínimos y fija las acciones de terceros por hash de commit, no por etiqueta.
- Mantén las dependencias al día.
Más información
- Arquitectura: componentes, flujo de una petición y CI/CD.
- API pública: reglas generales, errores y rutas.
- Esquema de la base de datos: tablas y áreas del esquema.
- Bot de Discord: comandos y permisos.
- Vantsgames: repositorio principal, despliegue y reversión.
- vants-faceit-webhook: validación del secreto de FACEIT.