🚀Debugging Microservices & Distributed Systems
3 min read

How To Implement Content Security Policy (CSP) Headers For Astro

Content Security Policy (CSP) acts like a shield against XSS attacks. These attacks are sneaky - they trick your browser into running malicious code by hiding it in content that seems trustworthy. CSP's job is to spot these tricks and shut them down, while also alerting you to any attempts it detects.

Content Security Policy is like a bouncer for your website. It tells the browser what content is allowed to load and from where. This helps prevent a whole bunch of nasty attacks, like Cross-Site Scripting (XSS) and data injection.

Content Security Policy (CSP) should be implemented as a response header, not a request header. Here’s why:

  1. CSP is a security mechanism enforced by the browser on the client-side.
  2. The server sends the CSP directives to the browser as part of its response.
  3. The browser then enforces these policies when loading and executing content.

So, in the context of Astro.js and web servers in general, CSP headers should be set on the server’s responses to the client. This means that when configuring CSP, we’re always dealing with response headers.

Implementing CSP in Astro

Let’s start with a basic CSP setup for an Astro site. We’ll use the astro.config.mjs file to add our headers.

import { defineConfig } from 'astro/config';
export default defineConfig({
server: {
headers: {
"Content-Security-Policy": "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';"
}
}
});

This configuration does a few things:

  1. default-src 'self': Only allows resources to be loaded from the same origin.
  2. script-src 'self' 'unsafe-inline': Allows scripts from the same origin and inline scripts (which Astro uses).
  3. style-src 'self' 'unsafe-inline': Allows styles from the same origin and inline styles.

The Astro CSP Gotcha

Astro has a unique architecture that can trip up CSP. It uses a technique called “partial hydration” where some components are static and others are interactive. This means your CSP needs to be flexible enough to allow for this hybrid approach.

Here’s a more comprehensive CSP for a typical Astro site.

export default defineConfig({
server: {
headers: {
"Content-Security-Policy": `
default-src 'self';
script-src 'self' 'unsafe-inline' 'unsafe-eval';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
font-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
block-all-mixed-content;
upgrade-insecure-requests;
`
}
}
});

This policy is more permissive but still secure. It allows for Astro’s hydration needs 'unsafe-eval' and common use cases like loading images from HTTPS sources.

Vercel Approach

With Vercel, you can use a vercel.json file in your project root:

{
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "Content-Security-Policy",
"value": "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';"
}
]
}
]
}

This applies the CSP header to all routes on your Vercel-deployed Astro site. All you have to do with git push to deploy your changes.

Cloudflare Approach

Cloudflare uses Page Rules to add headers. Here’s how you might set it up:

  1. Go to your Cloudflare dashboard
  2. Navigate to Rules > Page Rules
  3. Click on the ‘Modify Response Headers’ tab
  4. Click ‘Create rule’
  5. Click ‘Add Static Header to Response’
  6. Add a “CSP” Header:
    • Header Name: Content-Security-Policy
    • Value: Your CSP string

Cloudflare Page Rule

The advantage of Cloudflare’s approach is that you can easily update your CSP without redeploying your site.

Read Also


Related Articles

If you enjoyed this article, you might find these related pieces interesting as well.

Recommended Engineering Resources

Here are engineering resources I've personally vetted and use. They focus on skills you'll actually need to build and scale real projects - the kind of experience that gets you hired or promoted.

Imagine where you would be in two years if you actually took the time to learn every day. A little effort consistently adds up, shaping your skills, opening doors, and building the career you envision. Start now, and future you will thank you.


This article was originally published on https://www.trevorlasn.com/blog/csp-headers-astro. It was written by a human and polished using grammar tools for clarity.

Interested in a partnership? Shoot me an email at hi [at] trevorlasn.com with all relevant information.