Learning Astro - Security & Best Practices
Episode 12 of 24

Learning Astro - Security & Best Practices

This episode covers securing an Astro site: secure headers and Content Security Policy, XSS mitigation and content sanitization, securing API calls and tokens, and strategies for protecting sensitive content on static sites.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

A static site has no server-side database, but that does not mean it is immune to security problems. Episode 12 covers the security layers you must install: secure headers, Content Security Policy (CSP), cross-site scripting (XSS) mitigation, and token security.

Many attacks on modern sites do not target the server but the visitors: malicious scripts injected through content or comments, phishing links, or loading unknown resources. The best defense is prevention at the header and sanitization level — not just relying on one framework.

This episode equips you with a security checklist you can apply right after deployment.

Secure Headers and Content Security Policy

Installing Secure Headers

Secure headers are HTTP response headers that restrict browser behavior. Install them through your hosting platform's file. Example in vercel.json:

Secure headers di vercel.json
{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        { "key": "X-Content-Type-Options", "value": "nosniff" },
        { "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
        { "key": "Strict-Transport-Security", "value": "max-age=31536000; includeSubDomains" }
      ]
    }
  ]
}

The X-Content-Type-Options: nosniff header prevents the browser from guessing file types, and Strict-Transport-Security enforces HTTPS connections. All three close common gaps without code changes.

Content Security Policy

CSP controls which sources of scripts, styles, and images are allowed to load. It is the front-line defense against XSS. Example of a simple CSP:

CSP via meta tag
default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'

The script-src 'self' policy only allows scripts from your own domain — scripts from other sources are blocked by the browser. Other domains are added explicitly:

CSP dengan domain eksternal
script-src 'self' https://cdn.contoh.dev; img-src 'self' data:

When adding a CDN or analytics domain, register it in the CSP. Any violation will show up in the browser console — start from a strict policy and loosen it only when necessary.

XSS Mitigation and Content Sanitization

Astro Guards Against XSS by Default

One of Astro's strengths: all output is escaped automatically. Values like {variabel} are rendered as plain text, not HTML. This blocks script injection through untrusted data.

Sanitizing Content from External Sources

Content that comes from a CMS or user input must be sanitized before rendering. Astro provides the render() helper for content collection content that is already safe. For raw HTML from other sources, use a sanitization library:

JSSanitasi HTML sebelum dirender
import sanitizeHtml from "sanitize-html";
 
const htmlAman = sanitizeHtml(kontenDariCms, {
  allowedTags: ["b", "i", "em", "strong", "a"],
  allowedAttributes: { a: ["href", "target"] },
});

The sanitizeHtml(konten, { allowedTags }) function strips all disallowed tags. With a whitelist like the one above, only basic formatting and links pass through.

Secure API Calls and Token Handling

Tokens Only on the Server Side

Tokens and API keys must not end up in the client bundle. Remember the rule from episode 8: only PUBLIC_ variables are sent to the browser. Secret tokens are used at build time or in server endpoints:

JSToken server di frontmatter
const res = await fetch("https://api.contoh.dev/data", {
  headers: { Authorization: `Bearer ${import.meta.env.API_TOKEN}` },
});

import.meta.env.API_TOKEN only exists in the build process or the server runtime — it is never exposed in the HTML. Make sure that variable is set in the CI/CD environment, not committed.

Protecting Sensitive Content on Static Sites

Sensitive content — such as an internal dashboard — must not be rendered statically. Anyone who knows the URL can read it. The right solution: render that page on the server with authentication (episode 13), or move it to a separate application. For static sites, "hiding behind an obscure URL" is not security.

Warning

CSP is not a substitute for content sanitization, and sanitization is not a substitute for CSP. Install both: sanitization for incoming data, CSP as a safety net when something slips through.

Pre-Deployment Security Checklist

Check Before Launch

Before deploying to production, run this checklist:

Memeriksa header keamanan
curl -sI https://situs-kalian.dev | grep -i -E "x-content-type-options|strict-transport|content-security"

The curl -sI command fetches the response headers and filters the security-related ones. If the line is empty, the header is not installed.

Ongoing Auditing

Once the checklist passes, make checking part of your routine: verify headers on every deploy, review the CSP whenever you add a third-party script, and always sanitize input. Security is not a one-time step but a continuous process.

Conclusion

Episode 12 arms you with security practices: secure headers and CSP, XSS mitigation through default escaping and content sanitization, protecting tokens so they never leak to the client, and the awareness that sensitive content needs server authentication, not a secret URL.

The key takeaways:

  • Install secure headers and CSP before deployment.
  • Astro escapes all output by default — take advantage of it.
  • Sanitize HTML from external sources with a tag whitelist.
  • Secret tokens only at build time or in the server runtime.
  • Sensitive content needs authentication, not just a secret URL.
  • Check headers with curl -sI after every deployment.

In the next episode 13, we will cover authentication and protected content: authentication patterns for static sites, client-side auth with astro-auth or external providers, protecting routes and gated content, and session management with secure cookies. Your sensitive content will have a secure entry point.

Learning Astro - Security & Best Practices | Learning Astro