1dollar.website

Securing a site on Netlify

Netlify gives you HTTPS automatically, but it doesn't add security headers for you: you add them with a _headers file in your publish folder. The other common problems on Netlify are secret keys built into your JavaScript and files deployed by accident.

Last updated October 26, 2026

Prefer to fill in a form? Use the free security headers generator or the SPF and DMARC record generator.

Not sure whether your site has this?

Paste your address. The checkup is free and shows what's flagged.

What our checkup looks for

Our free checkup reads your site's headers, checks the HTTPS redirect, asks for files that should never be public, and checks your domain's email records. It recognises Netlify from its response headers.

The complete _headers file

Create a file named _headers (no extension) in the folder Netlify publishes, often public/ or dist/, so it ends up in the deployed site. This one block adds every recommended header. The Content Security Policy starts in report-only mode, so it changes nothing for visitors yet.

You can put the same headers in netlify.toml under [[headers]] instead. Use one place, not both.

How to fix it on Netlify

  1. Create a file named _headers in your publish folder (often public/ or dist/).
  2. Paste the lines below and redeploy.
  3. The Content-Security-Policy-Report-Only line changes nothing for visitors yet. After a week with no broken features (check your browser's console), rename it to Content-Security-Policy to switch it on.
Copy this
/*
  Strict-Transport-Security: max-age=31536000; includeSubDomains
  Content-Security-Policy-Report-Only: default-src 'self' https:; img-src 'self' https: data:; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; upgrade-insecure-requests
  X-Frame-Options: SAMEORIGIN
  X-Content-Type-Options: nosniff
  Referrer-Policy: strict-origin-when-cross-origin
  Permissions-Policy: camera=(), microphone=(), geolocation=()

HTTPS

Netlify provides a free certificate and redirects to HTTPS on its own once the certificate is active. If the checkup flags HTTPS, the domain's DNS usually isn't pointing at Netlify correctly yet.

How to fix it on Netlify

  1. In Netlify open Site configuration > Domain management > HTTPS.
  2. Click 'Verify DNS configuration', then provision the certificate. Netlify redirects to HTTPS automatically once it's active.

Keep secret keys out of your JavaScript

Anything your build puts into browser JavaScript can be read by every visitor. Sites built with an AI tool often call a payment or AI service straight from the browser with a secret key. Keep secret keys in Netlify's environment variables and use them only in Netlify Functions, never in front-end code.

How to fix it on Netlify

  1. Treat the key as stolen: create a new one in that service's dashboard and delete the old one today.
  2. Move every call that needs the secret key to your server (an API route or serverless function). Browser code should only ever hold publishable keys.
  3. Rebuild and redeploy, then search the new JavaScript files to confirm the key is gone.

Files deployed by accident

Netlify serves whatever is in your publish folder. If that's the project root instead of the build output, .env and .git go live with it. Source maps (.map files) let anyone rebuild your original code; turn them off in production builds.

Choose where your site runs

Netlify
  1. Treat every password and key in that file as stolen. Change them all now: database password, API keys, payment keys, email passwords.
  2. This file is being deployed as part of your site. Remove it from the folder you publish (e.g. public/ or the build output).
  3. Check your build settings so the project root isn't deployed as-is, then redeploy.
  4. Afterwards, open the address again in a private window and confirm it shows an error page.
Copy this
# Make sure files like these never reach your publish folder
.env
.env.*
.git/
Source maps
  1. Turn off public source maps in your build: Create React App: GENERATE_SOURCEMAP=false. Vite: build.sourcemap = false. Next.js: leave productionBrowserSourceMaps off. Webpack: devtool: false (or 'hidden-source-map').
  2. Delete the existing .map files from your server, or block them as shown below.
  3. If you need them for error tracking, upload them to your error tool privately instead of serving them.
nginx
location ~* \.map$ {
    return 404;
}

Your domain's email records

If your domain's DNS is on Netlify, add these in Netlify's DNS records for the domain. Otherwise add them wherever your DNS lives. Our email guide explains each one.

How to fix it

  1. Log in to wherever you manage your domain's DNS (your registrar, Cloudflare, etc.).
  2. Add both records below to example.com. If there's already a TXT record starting with v=spf1, replace it: a domain must have only one.
  3. Replace the <...> part with your email provider's SPF include: Google Workspace is _spf.google.com, Microsoft 365 is spf.protection.outlook.com. Add one for each service that sends email as you.
  4. If you're not sure every service that sends email as you is listed, start with p=none for two weeks and read the reports, then change it to p=quarantine.
dns
Type: TXT
Name: @
Value: v=spf1 include:<your email provider's SPF domain> -all

Type: TXT
Name: _dmarc
Value: v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com

How to check it worked

Each header should appear after your next deploy. Or run our free checkup again.

bash
curl -sI https://example.com | grep -iE 'strict-transport|x-frame|x-content-type|referrer-policy|permissions-policy|content-security'

Common mistakes

  • Putting _headers in the project root when your publish folder is dist/. It has to end up in the deployed site.
  • Using a VITE_ or NEXT_PUBLIC_ variable for a secret key. Those prefixes mean 'include this in browser code'.
  • Deploying the project root instead of the build folder.

What this can't tell you

We check from outside, so we can't see Netlify Functions' code or your environment variables. A code review can.

Check your own site, free

The free checkup shows how many results are flagged and how serious. For $1, the report picks the ones that matter for your site and writes each fix for your platform, with your own domain filled in.