Cómo funciona esta comprobación
Este check solo actúa si tu web ya envía una cabecera Content-Security-Policy; si no la envía, es el escáner de cabeceras quien lo marca. Scanaris lee la política completa y busca las dos palabras que la vacían: 'unsafe-inline', que permite ejecutar cualquier script o estilo escrito directamente en el HTML, y 'unsafe-eval', que permite convertir texto en código con eval y similares. Si aparece alguna, abre un hallazgo de severidad baja con la lista de debilidades encontradas. Es baja porque tener una CSP imperfecta sigue siendo mejor que no tenerla, pero la protección contra inyección de scripts, que es la razón de ser de la CSP, queda casi anulada.
Por qué importa
Una CSP estricta hace que, aunque un atacante consiga meter un <script> en tu página (por un comentario sin sanear, un parámetro reflejado o una librería comprometida), el navegador se niegue a ejecutarlo. Con 'unsafe-inline' en script-src, ese script inyectado se ejecuta igual: la cabecera está, el candado parece cerrado, pero la puerta está abierta. Dónde está la palabra importa: en script-src es grave; en style-src es un riesgo mucho menor que muchas webs aceptan por sus estilos en línea.
Cómo arreglarlo
1. Nonces para los scripts en línea
Un nonce es un valor aleatorio distinto en cada petición que pones en la cabecera y en cada etiqueta <script> legítima. El navegador ejecuta solo los scripts que llevan ese valor; un script inyectado no lo conoce.
Content-Security-Policy: script-src 'nonce-R4nd0m' 'strict-dynamic'; object-src 'none'; base-uri 'self'
Next.js lo hace en el middleware, generando el nonce y pasándolo a la cabecera y a los componentes; Nuxt, con un plugin de servidor que lo inyecta en cada respuesta (es lo que hace Scanaris); Express, con un middleware que lo guarda en res.locals y lo imprime en las plantillas.
2. Hashes para scripts fijos
Si un script en línea no cambia nunca, calcula su hash SHA-256 y ponlo en la política: 'sha256-…'. Sirve para fragmentos pequeños, como el de un gestor de etiquetas, sin montar nonces.
3. Mover el código a archivos
Los manejadores onclick="…" y los bloques de script en el HTML son la causa habitual de necesitar 'unsafe-inline'. Pásalos a archivos .js servidos desde tu dominio y desaparece la necesidad.
4. Quitar unsafe-eval
Suele exigirlo una librería antigua o un modo de desarrollo de un framework que se coló en producción. Comprueba en la consola del navegador qué lo pide y actualiza o sustituye esa pieza.
5. Desplegar en modo informe
Publica primero la política nueva como Content-Security-Policy-Report-Only con una directiva report-to o report-uri hacia un endpoint tuyo. Durante unos días recoge qué bloquearía, ajusta, y cuando los informes estén limpios cámbiala a la cabecera que bloquea.
Comprueba que está arreglado
curl -sI https://tudominio.com | grep -i "content-security-policy"
En script-src no debe aparecer 'unsafe-inline' ni 'unsafe-eval'. Después navega por tu web con la consola abierta: cualquier bloqueo aparece ahí con la directiva que lo causó. La teoría completa está en cabeceras de seguridad HTTP explicadas para humanos.
Preguntas frecuentes
Uso Tailwind o estilos en línea. ¿Tengo que quitar unsafe-inline de style-src?
Es deseable pero no urgente. Los estilos en línea no ejecutan código. Prioriza script-src; una política con 'unsafe-inline' solo en style-src protege de lo importante.
Google Tag Manager o un chat de soporte me obligan a relajar la política.
Casi todos tienen documentación de CSP: aceptan un nonce o publican los hashes y dominios que necesitan. Añade sus orígenes a script-src y connect-src en lugar de abrirlo todo.
¿La CSP me va a romper la web?
Solo si la pasas a bloquear sin probar. Por eso existe el modo informe: te enseña lo que rompería sin romperlo.