# Security

By generating static HTML at build time, static sites built with Nacelle offer security gains over server-renderered web apps by default. But there are additional steps you can take to secure your site against attackers looking to exploit cross-site scripting (XSS) vulnerabilities, packet sniffing, and more.

# Setting A CSP

A simple way to increase the security of your site is to properly set the HTTP headers, including the Content Security Policy (CSP), X-Frame-Options, and X-XSS-Protection headers. How these headers are set will vary from site to site. But while there is no universal configuration, there are common guiding principles that make the process of securing your site easier.

When setting the CSP, it's important to strike a balance between security and permissibility. If the CSP settings are too restrictive, your scripts, styles, fonts, and images might not be allowed to load.

WARNING

An overly-restrictive CSP can interfere with third-party analytics and UI add-ons, such as Google Analytics, Yotpo, Gorgias, etc.

Conversely, a CSP that is too relaxed can make your site vulnerable to bad actors. Fortunately, there are excellent tools for testing your CSP. Among those tools is Mozilla Observatory, which will assign your site a letter-grade security score and will help you identify specific opportunities for improving your site's security.

How you set your HTTP headers will depend on which service you are using to host your Nacelle site. Below are examples of how to set HTTP headers using Vercel and Netlify. In both cases, we are taking care to specify that remote font resources can be loaded from specific sources.

WARNING

Note that the CSP settings used here are for demonstration purposes only and are intentionally over-permissible. Think of these examples as a starting point, and take care to strengthen your CSP, particularly in the script-src and style-src fields.

# Vercel

Setting up a deployment with Vercel's CLI produces a vercel.json configuration file. We'll use the same vercel.json file to set security headers in a new headers object:

"headers": [
  {
    "source": "/(.*)",
    "headers": [
      {
        "key": "Content-Security-Policy",
        "value": "script-src 'self' 'unsafe-inline' https:; style-src 'self' 'unsafe-inline' https:; font-src 'self' https://fonts.gstatic.com https://use.typekit.net; img-src 'self' https:; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; connect-src 'self'; frame-src 'self'; object-src 'none'"
      },
      {
        "key": "Referrer-Policy",
        "value": "no-referrer-when-downgrade"
      },
      {
        "key": "X-Content-Type-Options",
        "value": "nosniff"
      },
      {
        "key": "X-Frame-Options",
        "value": "DENY"
      },
      {
        "key": "X-XSS-Protection",
        "value": "1; mode=block"
      }
    ]
  }
]

# Netlify

After following the steps outline in the Netlify Deployment docs, create a netlify.toml configuration file and set the headers as follows:

[[headers]]
  for = "/*"

  [headers.values]
    Content-Security-Policy = """
    script-src 'self' 'unsafe-inline' https:;
    style-src 'self' 'unsafe-inline' https:;
    font-src 'self' https://fonts.gstatic.com https://use.typekit.net;
    img-src 'self' https:;
    frame-ancestors 'none';
    base-uri 'self';
    form-action 'self';
    connect-src 'self';
    frame-src 'self';
    object-src 'none'
    """
    X-Content-Type-Options = "nosniff"
    X-Frame-Options = "DENY"
    X-XSS-Protection = "1; mode=block"
    Referrer-Policy = "no-referrer-when-downgrade"