Nivel BásicoGratis

Security headers checklist 2026 — CSP, HSTS, X-Frame, Referrer-Policy y más

Audit completo de HTTP security headers que cualquier aplicación moderna debe tener: ejemplos reales, configuración correcta, errores comunes y cómo reportarlos.

Gorka El Bochi11 de mayo de 202611 min

Deja de leer sobre bugs y empieza a cazarlos

Sin tarjeta · Academy gratis · cancela cuando quieras

Crear cuenta gratis

Respuesta rápida

Security headers son la primera línea de defensa contra XSS, clickjacking, MITM y info leaks. Audit mínimo en 2026: CSP (con frame-ancestors + sin unsafe-inline), HSTS (preload + includeSubDomains), X-Content-Type-Options nosniff, Referrer-Policy strict-origin-when-cross-origin, Cookies Secure + HttpOnly + SameSite=Lax, Permissions-Policy explícita. Reports de headers solos suelen ser info/low (€50-€200), pero como chain con otro bug pueden disparar la severity 2 niveles.


Tabla completa — headers que mirar

HeaderValor recomendadoQué previeneSeverity si falta
Strict-Transport-Securitymax-age=31536000; includeSubDomains; preloadMITM / downgrade HTTPSMedium
Content-Security-Policydefault-src 'self'; frame-ancestors 'none'; ...XSS, clickjacking, exfilMedium-High
X-Content-Type-OptionsnosniffMIME confusion XSSLow
X-Frame-OptionsDENY o SAMEORIGINClickjacking (legacy)Low (si hay CSP frame-ancestors)
Referrer-Policystrict-origin-when-cross-originToken leak via RefererLow-Medium
Permissions-Policycamera=(), microphone=(), geolocation=()Abuse de APIs sensiblesLow
Cross-Origin-Opener-Policysame-originSpectre, window.openerLow-Medium
Cross-Origin-Embedder-Policyrequire-corpSpectre, side-channelLow
Cross-Origin-Resource-Policysame-originCrossorigin leaksLow
Cache-Control (en endpoints auth)no-store, privateData leak via cacheMedium

Content-Security-Policy — el header rey

CSP es el más complejo y el más impactante. Una CSP mal hecha pasa todos los XSS; una CSP bien hecha bloquea incluso XSS reflejados.

Ejemplo de CSP correcta (SPA moderna)

css
Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-RANDOM123' https://js.stripe.com;
  style-src 'self' 'unsafe-inline';
  img-src 'self' data: https:;
  font-src 'self' data:;
  connect-src 'self' https://api.target.com wss://ws.target.com;
  frame-src https://js.stripe.com https://hooks.stripe.com;
  frame-ancestors 'none';
  form-action 'self';
  base-uri 'self';
  object-src 'none';
  upgrade-insecure-requests;
  report-uri /csp-report

Errores que matan la CSP

Anti-patternPor qué es malo
script-src 'unsafe-inline'Permite inline <script> → cualquier XSS reflejado pasa
script-src 'unsafe-eval'eval(), Function(), setTimeout(string) → gadget chains
script-src https:Permite scripts de cualquier HTTPS → no protege nada
script-src *.cdn.comSi el CDN sirve user content (JSONP) → bypass instantáneo
Sin frame-ancestorsClickjacking
Sin base-uri<base> injection → cambia el origen de scripts relativos
Sin form-actionForm hijacking en XSS to exfil credentials
default-src 'self' sin object-src 'none'<object data="data:..."> ejecuta Flash legacy

[!danger] frame-ancestors NO es suficiente frame-ancestors 'none' previene iframing tradicional, pero no previene window.open() popups con clickjacking via UI confusion. Para cerrar el vector completo: añade Cross-Origin-Opener-Policy: same-origin + verificación de window.top === window.self en JS crítico.

Test CSP

bash
# Ver el header
curl -sI https://target.com | grep -i content-security

# Evaluator oficial Google
# Pega la CSP en https://csp-evaluator.withgoogle.com/

# Buscar bypasses según las whitelisted domains
# https://github.com/PortSwigger/csp-bypass

HSTS — el header simple pero crítico

ini
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
DirectivaSignificado
max-age=315360001 año en segundos. Tiempo que el browser fuerza HTTPS
includeSubDomainsAplica a todos los subdomains. Crítico para evitar attacks via subdomain takeover http
preloadInscripción en la HSTS preload list de Chrome/Firefox (hardcoded)

Preload list

Inscríbete en hstspreload.org. Requisitos:

  • Servir HSTS con max-age >= 31536000, includeSubDomains, preload.
  • Redirect HTTP → HTTPS en root + en todos los subdomains.
  • Soportar HTTPS en todos los subdomains (incluso mail.target.com).

Cookies — los flags que cuentan

ini
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=3600
FlagQué haceCuándo es crítico
SecureSólo en HTTPSSiempre. Sin esto = leak via downgrade
HttpOnlyInaccesible desde JSSesiones, auth tokens — siempre
SameSite=LaxNo se envía en cross-site POSTsDefault sensato. Protege CSRF en mutations
SameSite=StrictNo se envía en NINGÚN cross-site requestPara tokens de máxima sensibilidad (banking)
SameSite=NoneSe envía en cross-site (necesita Secure)Cookies de third-party widgets (analytics, embeds)
__Host- prefixFuerza Secure, Path=/, sin DomainDefense in depth para auth
__Secure- prefixFuerza SecurePara cookies de auth/session

[!tip] SameSite Lax vs Strict en 2026 Chrome y Firefox ya hacen SameSite=Lax por default si no se especifica. Pero todavía hay endpoints en frameworks viejos que setean sin SameSite explícito → reportable. Strict rompe flows de OAuth/SSO porque la cookie no llega tras redirect → Lax es el sweet spot.


Referrer-Policy — el leak silencioso

sql
Referrer-Policy: strict-origin-when-cross-origin

Sin esta header, el browser envía el Referer completo (incluyendo path + query) a cualquier sitio externo al que linkees. Resultado: tokens de password reset, session IDs en query, OAuth codes — todos filtrados a third-parties.

ValorCuándo
no-referrerMáxima privacidad. Para apps sensibles (medical, financial)
strict-origin-when-cross-originDefault sensato en 2026. Origin completo same-origin, sólo origin cross-origin, nada cross-origin http→https
same-originSólo same-origin envía referrer, cross-origin nada
unsafe-urlNUNCA. Envía URL completa siempre

Reportable

URLs con tokens en query (?reset_token=, ?session=, ?code=) + sin Referrer-Policy restrictiva → al user hacer click en link externo, token se filtra al third-party. Severity Medium si el token sigue siendo válido.


Permissions-Policy — el moderno (ex Feature-Policy)

Antes era Feature-Policy. Renamed a Permissions-Policy en 2020+ y soporta más APIs.

ini
Permissions-Policy:
  camera=(),
  microphone=(),
  geolocation=(),
  payment=(self),
  usb=(),
  accelerometer=(),
  gyroscope=(),
  magnetometer=(),
  interest-cohort=()
  • camera=() → ningún origen puede acceder.
  • camera=(self) → sólo same-origin.
  • camera=(self "https://trusted.com") → same-origin + ese específico.
  • interest-cohort=() → opt-out de FLoC/Topics API tracking.

Reportable si la app embedded en iframe puede activar mic/camera/geolocation sin que el usuario lo espere → defense in depth.


COEP / COOP / CORP — cross-origin isolation

Necesarios para usar SharedArrayBuffer, performance.now() de alta precisión, y mitigar Spectre/Meltdown.

makefile
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-origin
  • COOP same-origin: tu window no comparte browsing context con popups cross-origin → cierra window.opener attacks.
  • COEP require-corp: todos los recursos cargados deben tener Cross-Origin-Resource-Policy o CORS. Activa "cross-origin isolation".
  • CORP same-origin: tus recursos sólo pueden ser cargados desde same-origin.

[!info] Cuándo activarlos Si tu app usa SharedArrayBuffer (WebAssembly, threading), necesitas COOP+COEP. Si tu app NO los usa, COOP same-origin es win gratuito para cerrar window.opener attacks. COEP rompe muchas apps third-party — implementar con cuidado.


Cómo testear todo de una

Herramientas

bash
# CLI rápido
curl -sI https://target.com

# Online — el estándar de facto
# https://securityheaders.com/?q=target.com
# https://observatory.mozilla.org/analyze/target.com

# CSP específico
# https://csp-evaluator.withgoogle.com/

Script manual de audit

bash
#!/bin/bash
URL="$1"

echo "=== Headers de $URL ==="
curl -sI "$URL" | grep -iE "(strict-transport|content-security|x-content-type|x-frame|referrer-policy|permissions-policy|cross-origin|set-cookie)"

echo -e "\n=== Cookies analysis ==="
curl -sI "$URL" | grep -i "set-cookie:" | while read -r line; do
    name=$(echo "$line" | sed 's/.*Set-Cookie: \([^=]*\)=.*/\1/i')
    flags=""
    echo "$line" | grep -qi "HttpOnly" || flags+="[NO HttpOnly] "
    echo "$line" | grep -qi "Secure" || flags+="[NO Secure] "
    echo "$line" | grep -qi "SameSite" || flags+="[NO SameSite] "
    [ -n "$flags" ] && echo "Cookie '$name': $flags"
done

Cómo reportarlo (sin ser low-info spam)

Headers sueltos casi siempre son info / low. Para que el report tenga valor:

  1. No mandes 10 reports separados. Un report con tabla de headers faltantes + impacto agregado.
  2. Demuestra impacto real. "CSP permite unsafe-inline" no es accionable. "CSP permite unsafe-inline Y existe un reflected XSS en /search → bypass directo" → Medium.
  3. Chain con otro bug. Header faltante + bug funcional = severity disparada.
  4. Bug bounty programs específicos. Algunos (Shopify, GitHub) explícitamente dicen "Missing security headers = N/A". Lee el scope.

Template de report headers

markdown
## Summary
La aplicación carece de las siguientes security headers, exponiendo a usuarios a clickjacking, XSS amplificado y leak de tokens via Referer.

## Headers afectados
| Header | Esperado | Actual |
|---|---|---|
| CSP | `default-src 'self'; frame-ancestors 'none'` | Ausente |
| HSTS | `max-age=31536000; includeSubDomains` | `max-age=300` |
| X-Frame-Options | `DENY` | Ausente |

## Impact
- Sin CSP: cualquier XSS reflejado/stored ejecuta sin restricción.
- HSTS débil: ventana de 5 min para MITM downgrade.
- Sin X-Frame-Options: clickjacking en /transfer endpoint posible.

## PoC clickjacking
[HTML con iframe del /transfer endpoint + overlay malicioso]

Hunting checklist

  • curl -sI al target → listar todos los response headers
  • securityheaders.com para grade objetivo (A+ es target)
  • CSP en csp-evaluator.withgoogle.com → buscar unsafe-inline, unsafe-eval, * whitelisted
  • HSTS: max-age >= 31536000 + includeSubDomains + preload
  • Cookies de auth: Secure + HttpOnly + SameSite=Lax|Strict
  • Referrer-Policy presente y restrictiva
  • X-Frame-Options o CSP frame-ancestors en TODAS las pages
  • Permissions-Policy disabling APIs no usadas
  • COOP same-origin mínimo en pages auth-críticas
  • Cache-Control en endpoints autenticados: no-store, private
  • Probar chain con XSS/CSRF/clickjacking para subir severity

Labs relacionados

Practica explotación de aplicaciones con headers mal configurados y chains de XSS → CSP bypass en labs de Security Headers.

Gratis · sin cuenta

La checklist que repaso en cada objetivo nuevo

47 comprobaciones ordenadas por coste: primero lo que te puede meter en un lío, luego lo barato, y al final lo caro — que es donde están los bounties grandes. Te la mando al correo ahora mismo.

Te das de baja en un clic, desde cualquier correo.

Practica esto en un lab

Security Headers

Resolver

Sigue aprendiendo · cuenta gratis

Guarda tu progreso, desbloquea payloads avanzados y rankea tus flags.

Crear cuenta
Premium · 1 técnica más

Hay un payload extra al final

Por qué `frame-ancestors 'none'` en CSP NO es suficiente para prevenir clickjacking en 2026, y la regla CSP que sí cierra todos los vectores.

Desbloquear

7,99 €/mes · cancela cuando quieras

Artículos relacionados

2.786

hunters entrenando

63

labs de hackeos reales

1.767

completaciones

$14.790

pagados por estos bugs

37 flags capturadas esta semana·Hackeos reales de HackerOne · YesWeHack · Bugcrowd·Sin permanencia·Academy gratis

La comunidad

Esto no es una plataforma con usuarios.Es gente rompiendo lo mismo que tú.

Dentro se pregunta, se enseña lo que se ha encontrado y se resuelve en grupo lo que atascaría a cualquiera solo. Se entra gratis: sin cuenta, sin plan y sin dejar el correo.

Entrar a la comunidad de BBLABS en Discord
Entrar al Discord

Es gratis y abierto. No hace falta tener cuenta en BBLABS para entrar.