Skip to content
Acecore

Achieving Secure Static Site Delivery with Cloudflare Pages

by Gui
Table of Contents
Achieving Secure Static Site Delivery with Cloudflare Pages

Cloudflare Pages is an excellent platform for hosting static sites. This article covers our actual deployment setup and security configuration using the _headers file.

Deployment Architecture: Why We Left Workers and Returned to Pages

Initially, we planned to use Cloudflare Workers for backend processing of the contact form. Workers allow server-side email sending and validation.

However, we encountered the following challenges during implementation:

  • Build complexity: Serving Astro’s build output through Workers required additional configuration
  • Debugging overhead: Behavioral differences between local wrangler dev and production
  • Cache control: Pages integrates more naturally with Cloudflare’s CDN

Ultimately, we adopted ssgform.com as an external service for the contact form, completely eliminating server-side processing. This removed the need for Workers, allowing us to deploy as a pure static site on Pages.

Security Configuration with _headers

On Cloudflare Pages, you can specify HTTP response headers in the public/_headers file. Below is an excerpt of the configuration we actually use.

Content-Security-Policy (CSP)

CSP is a critical header for preventing cross-site scripting (XSS) attacks. It specifies allowed resource origins using a whitelist approach.

Content-Security-Policy: default-src 'self';
  script-src 'self' 'unsafe-inline' https://challenges.cloudflare.com https://pagead2.googlesyndication.com;
  style-src 'self' 'unsafe-inline';
  img-src 'self' https://wsrv.nl https://images.unsplash.com data:;
  connect-src 'self' https://challenges.cloudflare.com https://pagead2.googlesyndication.com;
  frame-src https://challenges.cloudflare.com https://googleads.g.doubleclick.net;
  form-action https://ssgform.com;

Key points:

  • script-src: Allow Cloudflare Turnstile (challenges.cloudflare.com) and AdSense
  • img-src: Allow the image proxy wsrv.nl and Unsplash
  • form-action: Restrict form submissions to ssgform.com only
  • frame-src: Allow Turnstile iframes and AdSense ad frames

Other Security Headers

X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
  • X-Content-Type-Options: Prevent MIME sniffing
  • X-Frame-Options: Prevent iframe embedding as a clickjacking countermeasure
  • Referrer-Policy: Send only the origin for cross-origin requests
  • Permissions-Policy: Disable unnecessary browser APIs (camera, microphone, geolocation)

Cache Control

We set long-term caching for static assets and shorter caching for HTML.

/_astro/*
  Cache-Control: public, max-age=31536000, immutable

/*.html
  Cache-Control: public, max-age=3600

Files in the _astro/ directory output by Astro include content hashes, making it safe to cache them for one year with immutable. HTML has a moderate update frequency, so we limit it to a one-hour cache.

Pages Deployment Configuration

Cloudflare Pages project settings are simple:

SettingValue
Build commandnpx astro build
Output directorydist
Node.js version22

Once you connect a GitHub repository, pushes to the main branch trigger automatic deploys. Preview deployments are also auto-generated per PR, making reviews smoother.

Summary

The key is asking yourself: “Do I really need server-side processing?” By leveraging external services to eliminate Workers, both deployment and security management became simpler. CSP configuration via _headers takes some initial effort, but once written, it applies to all pages — making it a highly cost-effective security measure.

Deployment Architecture Evolution

Initial Setup

Delivered the static site on Cloudflare Pages.

Worker Migration

Migrated to Workers for contact form processing.

Return to Pages

Switched back to static delivery by adopting an external form service.

Security Hardening

Configured CSP and security headers via _headers.

Frequently Asked Questions
Should I choose Cloudflare Pages or Workers?
For static sites that don't require server-side processing, Pages is optimal. CDN integration is seamless and deployment is straightforward. Form processing can be handled by external services.
What security headers should be set in the _headers file?
Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, and Permissions-Policy are the essentials. Adjust CSP according to the external resources your site uses.
How do I allow AdSense and Analytics in CSP settings?
Add googletagmanager.com and googlesyndication.com domains to script-src. You may also need to allow related domains in img-src and connect-src.
G

Gui

CEO of Acecore. A versatile engineer covering system development, web production, infrastructure operations, and IT education. Enjoys solving organizational and human challenges through technology.

System development Web production Infrastructure operations IT education

Want to learn more about our services?

We provide comprehensive support including system development, web design, graphic design, and IT education.

Related Posts

Search articles