Sugerencias
← TIL
~3 min de lectura
#astro#security#performance#server-islands

[Astro 6] Seguridad Blindada: Implementando CSP nativo

[Astro 6] Seguridad Blindada: Implementando CSP nativo

BLUF: Astro 6 introduce soporte nativo para Content Security Policy (CSP), eliminando la necesidad de middlewares manuales para el hashing de scripts. La gran ventaja es que propaga automáticamente los nonces a las Server Islands (server:defer), permitiendo una política estricta sin romper la carga asíncrona. Dato vital: Si usas CSP estricta, debés migrar de ClientRouter a Native View Transitions para evitar violaciones de seguridad en navegaciones SPA.


Implementar una CSP estricta siempre fue un dolor de cabeza en frameworks de JS. Tenías que elegir entre ser inseguro usando 'unsafe-inline' o complicarte la vida con middlewares que inyectaran hashes manualmente.

Con la llegada de Astro 6.0 Stable, la seguridad pasa a ser declarativa y "smart". Tras aplicarlo en campa.dev, estos son los aprendizajes de trinchera que complementan mi estrategia de SEO técnico para sitios de alto rendimiento.

1. El adiós al middleware de seguridad

Antes, para tener una CSP real, necesitábamos un archivo src/middleware.ts que interceptara cada request para generar un hash. Eso añadía latencia y complejidad, algo que siempre critico de soluciones pesadas como WordPress.

// astro.config.mjs
export default defineConfig({
  security: {
    csp: {
      directive: {
        "default-src": ["'self'"],
        "script-src": ["'self'", "'strict-dynamic'"],
        "style-src": ["'self'", "'unsafe-inline'"], // Astro aún necesita inline styles para CSS crítico
        "connect-src": ["'self'", "https://vitals.vercel-insights.com"],
        "img-src": ["'self'", "data:", "https://i.ytimg.com"],
      },
      reportOnly: false,
    },
  },
});

Astro se encarga de escanear tus scripts en build-time y generar los hashes necesarios automáticamente.

2. Server Islands: Seguridad heredada

Uno de los mayores retos de las Server Islands (server:defer) era asegurar que los fragmentos que se cargan después del documento inicial sigan cumpliendo la política de seguridad.

Astro 6 resuelve esto propagando el nonce (número aleatorio de un solo uso) desde la página principal hacia el endpoint de la isla. Esto significa que si tu componente diferido inyecta un script, este será ejecutado porque Astro ya le dio el "visto bueno" de seguridad antes de enviarlo por el cable.

3. El gran "Gotcha": ClientRouter vs Native Transitions

Acá es donde muchos devs senior se van a golpear: CSP estricta y ClientRouter no se llevan bien.

El ClientRouter (el modo SPA de Astro) inyecta scripts dinámicamente durante la navegación. Si tenés una política de seguridad fuerte, el navegador va a bloquear estos scripts porque no puede validar su hash en una navegación que no sea un "full reload".

La solución en Astro 6: Usar el nuevo modo de Native View Transitions.

---
// En tu BaseLayout.astro
import { ClientRouter } from 'astro:transitions';
---
<!-- Astro 6 permite transiciones nativas que respetan la CSP -->
<ClientRouter transition:name="root" />

Asegurate de verificar en la documentación de Astro 6 cómo forzar el uso de la API nativa de transiciones del navegador para evitar falsos positivos de CSP.

4. Scripts de terceros (Vercel Analytics)

Si usás Vercel Analytics o Speed Insights, tu CSP los va a bloquear por defecto. Necesitás habilitar explícitamente sus dominios de conexión en connect-src:

  • https://vitals.vercel-insights.com
  • /_vercel/insights/*
Enlace copiado al portapapeles