¡Astro 5.9 tiene tu sitio bajo llave, con soporte experimental para Content Security Policy, renderizado de Markdown en content loaders, y más!
🔒 Refuerza las escotillas:
- Soporte experimental de Content Security Policy
- Renderizar Markdown en content loaders
- Deshabilitar estilos por defecto en imágenes responsivas experimentales
- Permitir a los adaptadores suprimir logs sobre soporte de características
Para actualizar un proyecto existente, usa la herramienta CLI automatizada @astrojs/upgrade. Alternativamente, actualiza manualmente ejecutando el comando de actualización para tu gestor de paquetes:
# Recommended:npx @astrojs/upgrade
# Manual:npm install astro@latestpnpm upgrade astro --latestyarn upgrade astro --latestSoporte experimental de Content Security Policy
Los ataques de Cross-site scripting (XSS) son algunas de las amenazas más comunes que enfrentan los sitios web. Por defecto, las páginas web pueden cargar cualquier script y estilo que quieran, de donde quieran. La defensa más potente contra los ataques XSS es limitar esto. Una Content Security Policy (CSP) te permite hacer eso, con herramientas para bloquear la página a una lista de recursos de confianza.
Si bien estas son herramientas potentes, pueden ser difíciles de implementar a mano: es mucho más fácil si tu framework puede hacerlo por ti. Astro 5.9 introduce soporte experimental para CSP out of the box, haciendo más fácil asegurar tus proyectos de Astro. Esta es la solicitud de característica más votada de Astro hasta ahora, y ciertamente nos tomamos nuestro tiempo para implementarla. ¡Esperamos que valga la espera!
Diseñamos la característica para funcionar en todos los modos de renderizado de Astro (páginas estáticas, páginas dinámicas y single page applications),
con máxima flexibilidad y type-safety en mente. ¡Lo oíste bien! Puedes descartar el desagradable workaround de unsafe-inline, usar todas las características de Astro que te gustan,
cualquier adaptador para cualquier runtime, y añadir una capa extra de seguridad a tu sitio.
Cómo funciona
Una de las razones por las que los usuarios gustan de Astro es porque funciona en todas partes – static hosts, serverless hosts, Node.js, edge runtimes, y con muchas librerías de frontend (React, Vue, Svelte, etc). Por esto, una solución CSP de Astro debe funcionar en todas partes con cualquier librería.
Empezamos considerando dos enfoques comunes para soportar CSP:
- El header
nonce, que genera un valor aleatorio para cada petición y lo inyecta en el HTML. - Calcular hashes de todos los recursos enviados al browser, asegurando que solo los scripts y estilos que esperas que se ejecuten serán ejecutados.
Mientras que el header nonce es directo de implementar, requiere una función de servidor/edge que sea capaz de generar
el valor aleatorio de nonce, añadir el header Content-Security-Policy al objeto Response, y reescribir el HTML para inyectar el valor de nonce para cada elemento <script> y <style>.
Esta solución no funcionaría para sitios web que se sirven desde static hosts ej. GitHub pages, y no funcionaría para Single Page Applications (SPAs)
donde los scripts y estilos podrían inyectarse dinámicamente durante el ciclo de vida de la aplicación.
La generación de hashes es más compleja de implementar porque requiere conocer el contenido exacto de cada script y stylesheet en la página. Sin embargo, puede soportar más casos de uso que el header nonce, así que nuestra elección estaba clara a pesar de que otra bifurcación en el camino nos esperaba.
El estándar CSP permite que los hashes se proporcionen al browser ya sea vía el header Response llamado Content-Security-Policy, o usando un elemento <meta> llamado http-equiv='content-security-policy'. Como puedes haber adivinado, usar el header Response no funcionaría para Astro, porque dejaría fuera a los sitios web estáticos y las SPAs. Por esta razón, decidimos usar el elemento <meta> para proporcionar el CSP al browser.
El resultado final es que el CSP de Astro generará el elemento <meta> por ti, con todos los hashes de los scripts y estilos que se usarán en la página, ¡incluso los que se cargarán dinámicamente!
Uso
Para probar el CSP de Astro en tus propios proyectos hoy, habilita el nuevo flag experimental:
import { defineConfig } from "astro/config"
export default defineConfig({ experimental: { csp: true }})Si ya usas el header Content-Security-Policy en tu sitio web vía middleware u otros medios, puedes seguir usándolo, y el browser usará la política más estricta del header y del elemento <meta>.
¡Pero no nos detuvimos ahí! Astro te da más control sobre ese contenido del <meta> vía configuración. Puedes cambiar el algoritmo por defecto, insertar directivas adicionales, y más:
import { defineConfig } from "astro/config"
export default defineConfig({ experimental: { csp: { // change the default algorithm algorithm: "`SHA-512", // insert additional directives directives: [ "default-src: 'self'", "image-src: 'https://images.cdn.example.com'" ], // add more information to the `style-src` directive styleDirective: { hashes: [ "sha384-somehash" // hash generated for some external style e.g. white label, etc. ], // **Override** default resources resources: ["self", "https://styles.cdn.example.com"] },
// add more information to the `script-src` directive scriptDirective: { hashes: [ "sha384-somehash" // hash generated for some external script e.g. analytics, jQuery, etc. ], // **Override** default resources resources: ["self", "https://script.cdn.example.com"], // Toggle the keyword `strict-dynamic` strictDynamic: true } } }})Para más detalles, consulta la documentación experimental de CSP.
Renderizar Markdown en content loaders
Las content collections de Astro siempre han soportado renderizar archivos Markdown usando la función render() y el componente <Content />, y Astro 5 añadió soporte para que cualquier loader renderice cualquier contenido HTML. Sin embargo, si querías renderizar contenido Markdown en un content loader, tenías que manejar el parsing de Markdown tú mismo. Esto podía ser confuso ya que era inconsistente con cómo se renderizaba Markdown en otras partes de tu sitio, y no usaba la misma configuración de Markdown.
Astro 5.9 añade una nueva función helper al contexto del loader - renderMarkdown - que te permite renderizar contenido Markdown directamente dentro de tus loaders. Usa los mismos ajustes y plugins que el renderer usado para archivos Markdown en Astro, incluyendo cualquier ajuste de Markdown configurado en el proyecto de Astro.
La función renderMarkdown está disponible en el contexto del loader, y devuelve un objeto con dos propiedades: html y metadata. Estas coinciden con la propiedad rendered de las content entries en las content collections, así que pueden usarse para añadir fácilmente soporte para render() en un loader.
import type { Loader } from 'astro/loaders';import { loadFromCMS } from './cms';
export function myLoader(settings): Loader { return { name: 'my-loader', async load({ renderMarkdown, store }) { const entries = await loadFromCMS(); store.clear(); for (const entry of entries) { // Assume each entry has a 'content' field with Markdown content store.set(entry.id, { id: entry.id, data: entry, rendered: await renderMarkdown(entry.content), }); } }, };}Ahora, incluso con tu loader personalizado, puedes acceder a render() y <Content /> tal como si tu contenido Markdown estuviera almacenado localmente en tu proyecto:
---import { getEntry, render } from 'astro:content';const entry = await getEntry('my-collection', Astro.params.id);const { Content } = await render(entry);---<Content />Para más detalles, consulta la documentación de content loaders.
Deshabilitar estilos por defecto en imágenes responsivas experimentales
Al usar imágenes responsivas experimentales, Astro aplica estilos por defecto para asegurar que las imágenes se redimensionen correctamente. En la mayoría de los casos esto es lo que quieres – y se aplican con baja especificidad para que tus propios estilos los sobrescriban.
Sin embargo en algunos casos puedes querer deshabilitar estos estilos por defecto completamente. Esto es particularmente útil cuando se usa Tailwind 4, porque usa CSS cascade layers para aplicar estilos, haciendo difícil sobrescribir los estilos por defecto de Astro.
Astro 5.8.1 añadió una nueva opción de configuración booleana image.experimentalDefaultStyles para aplicar estos estilos por defecto. Por defecto es true, proporcionando el comportamiento actual de imágenes responsivas. Pero si prefieres no pelear con Tailwind 4, estableciendo estilos !important por todas partes, puedes simplemente deshabilitar esta opción en tu configuración de Astro:
export default { image: { experimentalDefaultStyles: false, }, experimental: { responsiveImages: true, },};Para más detalles, consulta la documentación de imágenes responsivas experimentales.
Permitir a los adaptadores suprimir logs sobre soporte de características
Los adaptadores de Astro pueden declarar si soportan o no ciertas características de Astro, y si ese soporte es estable o experimental.
Durante los builds, Astro logueará un warning o error si un sitio está usando características que no están soportadas por el adaptador. Sin embargo, a veces un adaptador puede necesitar loguear mensajes más específicos para ayudar a los usuarios a resolver el problema. Anteriormente esto podía ser confuso, ya que estos logs personalizados se imprimían además de los generados por Astro y podían parecer contradecirlos.
Astro 5.9 añade una opción para permitir a los adaptadores suprimir el logging de características no soportadas. Un autor de adaptador puede añadir suppress: "all" (para suprimir tanto el mensaje por defecto como el personalizado) o suppress: "default" (para suprimir solo el mensaje por defecto de Astro):
setAdapter({ name: 'my-astro-integration', supportedAstroFeatures: { staticOutput: "stable", hybridOutput: "stable", sharpImageService: { support: "limited", message: "The sharp image service isn't available in the deploy environment, but will be used by prerendered pages on build.", suppress: "default", }, }})Para más detalles, consulta la referencia de la Adapters API.
Comunidad
El core team de Astro es:
Ben Holmes , Caleb Jasik , Chris Swithinbank , Emanuele Stoppa , Erika , Florian Lefebvre , Fred Schott , Fuzzy , HiDeoo , Luiz Ferraz , Matt Kane , Matthew Phillips , Nate Moore , Reuben Tier , Sarah Rainsberger , and Yan Thomas .
Gracias a todos los demás contribuidores que ayudaron a hacer posible Astro 5.9 con adiciones y mejoras de código y documentación, incluyendo:
☘, Adriel Martinez, Alexander Niebuhr, Ankur Oberoi, Ariel K, Armand Philippot, Arpan Patel, Ben Limmer, Bjorn Lu, Bugo, Cansin Acarer, Daniel Puscher, Elliot Dong, Hiromasa Fujimori, Hunter Bertoson, Igor Teplostanski, JiPai, Joe, Jonás Perusquía Morales, Junseong Park, Juraj Kapsz, kato takeshi, Kenzo Fachin, knj, liruifengv, Louis Escher, Nin3, Paul Valladares, Reuben Tier, Robin Bühler, Stephen Hendricks, sugardave, Thomas Bonnet, and vivek lokhande.


