Saltar al contenido

Fundamentos de seguridad

Faltan cabeceras de seguridad: cuándo importa de verdad

Que falten cabeceras de seguridad es el hallazgo que más imprime nuestro escáner. Contra qué protegen y cuándo son la línea menos urgente de tu informe.

Vlad Tkachenko9 min de lectura
La lista de cabeceras que un sitio devuelve con cada página, con cuatro de sus filas rayadas y vacías donde iría un valor.

En resumen

  • Que falten cabeceras de seguridad es el hallazgo más común que existe y, por sí solo, dice casi nada sobre si alguien puede llegar a tus datos.
  • Escaneamos 30.998 apps en producción. Dos de cada tres de las que tenían cabeceras faltantes no tenían nada más mal.
  • Aun así vale la pena arreglarlo, y va después de las cosas que deciden quién puede leer tu base de datos.
  • En algunos dominios de builders no puedes ponerlas tú, y dejarlas así es una respuesta razonable.

Tu escaneo vuelve y casi todas las líneas están en verde. Una está en ámbar: faltan algunas cabeceras de seguridad del navegador. Es lo único de la página que tiene color, así que parece lo primero de lo que hay que ocuparse.

Aquí está la parte que la mayoría de los consejos sobre esto se equivocan. Que falten cabeceras de seguridad es el hallazgo que más imprimimos y, por sí solo, no te dice casi nada sobre si alguien puede llegar a tus datos. Tratarlo como una brecha significa o arreglarlo con prisa por delante de las cosas que de verdad deciden quién lee tu base de datos, o aprender que las líneas ámbar son ruido, que es peor.

Entre el 12 y el 14 de agosto de 2026 pasamos las mismas nueve comprobaciones externas sobre 30.998 apps en producción hechas con Lovable, Bolt, v0, Replit y Base44. De las apps de las que esta comprobación obtuvo respuesta, a 30.756 de 30.981 les faltaba al menos una cabecera. Las cifras completas están en nuestro informe de escaneo.

¿Es un problema que falten cabeceras de seguridad?

Es un hueco real y casi siempre la línea menos urgente de tu informe.

Una cabecera de seguridad es una instrucción corta que tu servidor adjunta a cada página que envía, dirigida al navegador de la persona que visita y no a la persona. No dejes que otra web meta esta página dentro de un marco. No adivines qué tipo de archivo es este. No pases mi dirección completa cuando alguien haga clic en un enlace hacia fuera. Son notas para un ayudante que hace lo que le diga cualquier web.

El resto de tu informe va de cerraduras. Si Row Level Security está activado, si hay una clave secreta en tu código, si un bucket de almacenamiento lista su contenido: eso decide quién puede llegar a tus datos siquiera. Las notas y las cerraduras se quieren las dos, y la nota que nunca escribiste no es por lo que la gente pierde una base de datos.

Nuestra calificación lo trata así. Una cabecera que falta resta cinco puntos sobre cien y no limita el techo, así que una app cuyo único hallazgo es este sale con 95 y una nota A.

Qué encontramos en 30.998 apps

Las cabeceras faltantes aparecieron casi en todas partes, y apenas se movieron con el resto del informe.

25.821 de esas apps obtuvieron respuesta de las nueve comprobaciones, que es el grupo donde "no había nada más" significa algo. De ellas, a 25.606 les faltaba al menos una cabecera y 215 tenían las cinco.

Las apps a las que les faltaban cabeceras no tenían más probabilidad de tener algo más mal que las que tenían las cinco.

De las 25.606 apps a las que les faltaba al menos una cabecera, 17.043 no tenían nada más mal. Dos de cada tres. Era el único problema de su informe.

Ahora lee la otra fila, que es la parte que nos sorprendió. De las 215 apps que tenían las cinco cabeceras puestas, 145 tenían algo más mal. Esa es una tasa de problemas reales más alta que entre las apps con cabeceras faltantes, no más baja.

No medimos por qué, y la lectura honesta es estrecha: sea lo que sea lo que encontraron estos escaneos, el hallazgo de cabeceras no lo predijo. Una app con un juego perfecto de cabeceras no era una app más segura en nuestros datos. La explicación más probable es que poner cabeceras siquiera implica que alguien configuró un hosting de verdad, lo que suele implicar una app más grande con más cosas que hacer mal, pero eso es una suposición y no la hemos comprobado.

Si quieres ver qué líneas de estas produce tu propia app, el escaneo es gratuito, tarda unos 20 segundos y no necesita cuenta: escanea tu app.

Qué hace realmente cada cabecera

Cada una apaga un comportamiento del navegador que viene activado de fábrica.

CabeceraQué le dice al navegadorQué permite su ausencia
Content-Security-PolicyDesde qué sitios puede esta página cargar código y estilosUn script inyectado puede enviar datos a donde quiera
Strict-Transport-SecurityVuelve siempre por HTTPS, nunca por HTTP a secasUna visita en una red no fiable puede ser empujada a HTTP a secas
X-Frame-OptionsNo dejes que otro sitio muestre esta página dentro de un marcoTu página puede cargarse de forma invisible dentro de la de otra persona
X-Content-Type-OptionsFíate del tipo de archivo que te di y no lo adivines por el contenidoUn archivo que alguien subió puede servirse como un tipo de archivo distinto
Referrer-PolicyCuánto de esta dirección pasar cuando alguien hace clic hacia fueraURLs completas, con todo lo que lleven dentro, llegan a servidores ajenos

Dos de ellas se solapan, y el escáner lo tiene en cuenta. Una Content-Security-Policy que contenga frame-ancestors hace el mismo trabajo que X-Frame-Options, así que nuestra comprobación cuenta cualquiera de las dos y no exige las dos.

Cuándo una cabecera que falta es todo el problema

Cuando tu app tiene algo que merezca la pena pulsar mientras alguien tiene la sesión iniciada.

Ese es el caso del clickjacking, y es el único que funciona sin ningún otro error. Alguien carga tu app en un marco invisible dentro de una página que controla y pone sus propios botones encima de los tuyos, de modo que quien ya tiene la sesión iniciada pulsa lo que parece su página y da en un control tuyo: el botón que borra una cuenta, aprueba una transferencia o cambia una dirección de correo.

Con la cabecera, el navegador se niega a dibujar tu página dentro de otro sitio. Sin ella, eso es algo perfectamente previsto.

La persona tiene la sesión iniciada, así que la acción lleva su sesión detrás. No hace falta que nada de tu base de datos esté mal configurado. Lo que hace que funcione es que al navegador nunca se le dijo que se negara.

Referrer-Policy tiene una versión más pequeña de la misma forma. Si una página tuya con sesión iniciada lleva algo identificativo en la URL y enlaza hacia fuera a un servidor de imágenes o a un script de analítica, la dirección entera viaja con el clic. Quien gestione ese otro servidor ve dónde estaba tu usuario.

Las otras tres son condicionales. Importan cuando ya ha salido algo mal, y su trabajo es que quede pequeño. Una Content-Security-Policy limita lo que un script inyectado puede hacer con su acceso. X-Content-Type-Options importa si desconocidos pueden subirte archivos. Strict-Transport-Security cubre a quien usa tu app en una red que no controla.

¿Necesito cabeceras de seguridad?

Sí. Son baratas, y van después de los hallazgos que deciden quién puede leer tu base de datos.

El orden que se desprende de la medición de arriba: primero todo lo crítico o alto de tu informe, las cabeceras después. Si en tu informe solo está esta línea, como les pasaba a 17.043 de las apps que escaneamos, entonces las cabeceras encabezan tu lista por defecto.

Dos de las cinco no cuestan nada. X-Content-Type-Options: nosniff y Referrer-Policy: strict-origin-when-cross-origin son una línea cada una, no tienen un valor equivocado que elegir y no pueden romper una app que funciona. X-Frame-Options: DENY también es una línea, y conviene mirarla antes si incrustas tu propia app en algún sitio a propósito.

Content-Security-Policy es la que da trabajo de verdad. Un primer intento suele bloquear algo que tu propia página necesitaba, y el síntoma es una función que deja de funcionar sin avisar. Publícala como Content-Security-Policy-Report-Only, que te dice qué habría bloqueado sin bloquear nada, y lee los informes de una semana antes de activarla.

Cómo añadirlas

En lo que de verdad sirve tu app a internet, que muchas veces no es el sitio donde la construyes.

La mayoría de los builders despliegan en un hosting que es dueño de la respuesta, así que el ajuste vive allí. En Vercel es headers dentro de vercel.json. En Netlify y Cloudflare Pages es un archivo _headers en la raíz de lo que publicas. Detrás del proxy de Cloudflare es una Transform Rule. Si tienes tu propio servidor, es tu configuración de nginx o de Caddy.

Lo que hay que saber de las cabeceras una vez puestas es que se caen sin que nadie las toque. Mudarte a un dominio propio, poner un proxy delante, cambiar de hosting, tocar la configuración del framework: las cabeceras que añadiste viven en uno de esos sitios, y cualquiera de esos movimientos puede dejarlas atrás. Nada te avisa. La página sigue funcionando y el ajuste ya no está.

Para eso está Reeve Monitor. Vuelve a pasar la comprobación completa cada hora en hasta tres apps, vigila la disponibilidad cada 60 segundos y te avisa cuando cambia un resultado, en vez de esperar a que mires. Monitor vigila y nada más, así que si además quieres una copia de tu base de datos en un sitio al que tu builder no llegue, eso es Care, y cubre Supabase.

Qué hacer ahora mismo

Qué hacer

  • Lee primero el resto de tu informe. Si hay algo marcado como crítico o alto, ese es el trabajo, y las cabeceras esperan.
  • Pon hoy X-Content-Type-Options: nosniff y Referrer-Policy: strict-origin-when-cross-origin. Una línea cada una, nada que decidir, nada que romper.
  • Pon X-Frame-Options: DENY si la gente inicia sesión en tu app y puede hacer algo importante con un solo clic.
  • Deja Content-Security-Policy para el final y arráncala en modo report-only, para enterarte tú antes que tus visitantes de lo que rompe.
  • Si estás en un subdominio de builder sin ajuste de cabeceras, deja el hallazgo en paz. Todavía no es tuyo.
  • Vuelve a comprobarlas después de cambiar de dominio, poner un proxy o mudarte de hosting. Es cuando desaparecen.

Las cabeceras merecen una tarde tranquila una vez que el resto del informe está limpio. Si prefieres recorrer la lista entera en orden, la lista de seguridad de 10 minutos cubre qué apagar en una app recién lanzada, y los hallazgos que sí deciden quién lee tu base de datos son los primeros que hay que quitar de en medio.

Preguntas frecuentes

Mi escaneo dice que faltan cabeceras de seguridad. ¿Me han hackeado la app?

No. Una cabecera que falta es un ajuste que nunca se activó, y no es prueba de que haya ocurrido nada. En el hallazgo no interviene nadie que haya llegado a tus datos ni a tu cuenta. Describe una instrucción que tu sitio podría estar dando a los navegadores que lo visitan y ahora mismo no da.

¿Qué cabecera de seguridad debería poner primero?

X-Content-Type-Options y Referrer-Policy, porque ambas son una sola línea, ninguna tiene un valor equivocado que elegir y ninguna puede romper una app que funciona. Después X-Frame-Options, si la gente inicia sesión en tu app. Después Strict-Transport-Security. Content-Security-Policy la última, porque es la única de las cinco que exige pensar de verdad y la única que puede impedir que se ejecuten tus propios scripts.

Estoy en el dominio por defecto de mi builder y no hay ningún ajuste para cabeceras. ¿Ahora qué?

Déjalas. Cuando tu app se sirve desde un subdominio de la plataforma, las cabeceras de respuesta son decisión de la plataforma y no tuya, y no hay ningún archivo que puedas añadir que las cambie. Conecta un dominio propio si quieres controlar esto, porque el dominio es lo que te deja poner tu propio hosting o un proxy delante de la app. Hasta entonces, dedica el esfuerzo a los hallazgos que sí te toca arreglar.

¿Puede una Content-Security-Policy romper mi app?

Sí, y ese es el resultado normal de un primer intento. Una política que no permite scripts en línea detendrá los scripts en línea, incluidos los que generó tu builder, y la página se queda en blanco o pierde una función, con un error que solo aparece en la consola del navegador. Empieza con Content-Security-Policy-Report-Only, que informa de lo que habría bloqueado y no bloquea nada, y lee los informes durante una semana antes de activarla de verdad.

¿Ayudan las cabeceras de seguridad si mi base de datos la puede leer cualquiera?

No. Las cabeceras son instrucciones para los navegadores que visitan tu sitio, y quien lee tu base de datos directamente no está usando un navegador ni visitando tu sitio. Esa petición va directa a tu proveedor de base de datos y no toca tus páginas nunca, así que ninguna cabecera puesta en ellas se le aplica. Eso lo decide Row Level Security.

Escrito por

Vlad Tkachenko

Fundador de Reeve

Me paso el día mirando apps creadas con Lovable, Bolt, v0, Cursor y Replit, y la corta lista de errores que aparecen en ellas una y otra vez.

Más sobre el autor

Sigue leyendo

Todos los artículos

¿No sabes cómo está tu propia app?

Haz un escaneo gratuito y obtén una nota clara de la A a la F en unos 20 segundos. Sin cuenta y sin tarjeta.

Analizar mi app gratis

Comprobación externa automatizada, no una auditoría completa. La ausencia de hallazgos no es garantía de seguridad.