Cómo es un buen conjunto de cabeceras
strict-transport-security: max-age=31536000; includeSubDomains; preload
content-security-policy: default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests
x-content-type-options: nosniff
x-frame-options: DENY
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(), payment=()
cross-origin-opener-policy: same-origin
cross-origin-resource-policy: same-origin Eso es lo que envía este sitio. Para una aplicación con scripts en línea, la CSP cambia a nonces: script-src 'nonce-<aleatorio por respuesta>' 'strict-dynamic', que es a la vez más estricta y más fácil de mantener que una lista de hosts.
Cómo razona la evaluación de la CSP
Una CSP existe para limitar lo que puede hacer un atacante una vez que ha encontrado un punto de inyección. Así que la evaluación pregunta: dada una cadena inyectada, ¿pueden ejecutarse scripts? 'unsafe-inline' sin nonces dice que sí. Una fuente comodín o de esquema (*, https:, data:) dice que sí. Un host que sirve scripts elegibles por el atacante (CDN públicas con AngularJS antiguo, endpoints JSONP en googleapis.com, buckets de almacenamiento) dice que sí, por eso una larga lista de CDN populares es más débil de lo que parece. La ausencia de object-src y base-uri son las dos directivas que la gente olvida y que vuelven a abrir la puerta. Las directivas restantes (frame-ancestors, form-action, default-src) importan para el clickjacking y la exfiltración de datos más que para la ejecución de scripts, así que se valoran menos.
Dónde fijar las cabeceras
- nginx:
add_header Nombre "valor" always;— recuerda que unadd_headerdentro de unlocationanula todos los del nivel server (pruébalo con el probador de location de nginx). - Apache:
Header always set Nombre "valor"en el vhost o en .htaccess (mod_headers). - Cloudflare: HSTS en SSL/TLS → Edge Certificates; otras cabeceras mediante Transform Rules → Modify Response Header, que también funciona para orígenes que no puedes cambiar.
- Frameworks de aplicación: helmet (Node), secure_headers (Rails), django-csp, middleware de Laravel — estos también generan nonces por respuesta.
Desplegar una CSP con seguridad
- Envíala como
Content-Security-Policy-Report-Onlycon un endpointreport-toy observa los informes durante una semana. - Corrige las violaciones reales (manejadores en línea, widgets de terceros), ignora el ruido de las extensiones del navegador.
- Cambia el nombre de la cabecera a
Content-Security-Policy. Conserva report-only para probar el siguiente cambio.
Preguntas
¿Qué cabeceras importan más?
Para un sitio con cualquier interacción de usuario: primero Content-Security-Policy, luego Strict-Transport-Security y X-Content-Type-Options. Las políticas de framing y referrer son baratas de añadir. El resto es higiene: ocultar versiones, marcar cookies, eliminar cabeceras obsoletas.
¿Por qué mi CSP se califica como débil si solo lista hosts de confianza?
Porque la confianza no es la cuestión; la cuestión es si algún script de esos hosts puede hacerse ejecutar código del atacante. Las CDN públicas alojan miles de versiones de bibliotecas, algunas con gadgets conocidos (plantillas AngularJS, callbacks JSONP). Una política basada en nonces con strict-dynamic no tiene ese problema, y esta página la califica como la configuración más fuerte.
¿Sigue siendo útil X-XSS-Protection?
No. Chrome eliminó el auditor XSS en 2019, Edge en 2018; Firefox nunca lo tuvo. La cabecera es inofensiva como «0» y era dañina como «1; mode=block» en navegadores antiguos. Elimínala y usa CSP.
¿Cómo obtengo las cabeceras de una página que redirige?
curl -sIL https://example.com/ imprime cada respuesta de la cadena. Pégalo todo; se califica la última respuesta y se listan las redirecciones. Comprueba que http:// redirige a https:// en un solo salto.
¿La nota coincide con la de securityheaders.com?
Aproximadamente: ambos cuentan las mismas seis cabeceras principales. Esta página evalúa además el contenido de la CSP en lugar de solo su presencia, y resta por filtraciones y cabeceras obsoletas, así que un sitio con una CSP débil puntúa menos aquí.