Tuning the security of an Astro site
Where you set the headers on Astro depends on your output. A server-rendered (SSR) site can set them in middleware; a static build serves no headers from Astro, so then they belong on the host. Below, per finding, where the fix lives.
Response headers (HSTS, clickjacking, MIME sniffing, referrer, permissions)
When you run with an adapter (SSR), set them in src/middleware, adjusting the response after next(). For a static build, set them in your host's header config (a _headers file on Netlify or Cloudflare Pages, or vercel.json), because a static page has no server to send them from.
import { defineMiddleware } from 'astro:middleware';
export const onRequest = defineMiddleware(async (context, next) => {
const response = await next();
response.headers.set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
response.headers.set('X-Frame-Options', 'SAMEORIGIN');
response.headers.set('X-Content-Type-Options', 'nosniff');
response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');
response.headers.set('Permissions-Policy', 'camera=(), microphone=(), geolocation=()');
return response;
});/*
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()In the page (a hash on a script, trackers after consent)
An integrity hash, or allowing an external script, belongs in the .astro component that renders the script. Trackers that load only after consent are handled with a consent manager or tag manager.
The connection (HTTPS and the certificate)
Forcing HTTPS and the certificate are your host or CDN. Make sure http redirects to https and the certificate is valid and not expired. Most hosts and CDNs do this with a toggle or a free Let's Encrypt certificate.
DNS records (SPF, DMARC, DNSSEC, IPv6)
These sit apart from your site: they are records at your domain. Set them with your DNS provider or domain registrar, not in your CMS or on your host. SPF and DMARC govern who may send mail as your domain, DNSSEC signs your DNS, and IPv6 is the one where the host has to offer an AAAA record and a connection before you can add it.