Netlify
Security Guide

How to Secure Your Netlify App

Last updated: January 12, 2026

Netlify serves static sites from a CDN, which means security configuration works differently than server-based platforms. You can't set headers in application code — you need the _headers file. Environment variables split into build-time (embedded in output) and runtime (Functions only). And Netlify Functions are fully public endpoints with no built-in auth. This guide covers the Netlify-specific details.

Why Security Matters for Netlify

Key Security Concerns

Security headers require _headers file or netlify.toml - not automatic
Build-time env vars are baked into static HTML - use runtime for secrets
Netlify Forms are public endpoints - spam attacks without Akismet/reCAPTCHA
Deploy Previews can expose staging data unless password-protected
Functions timeout at 10s (26s paid) - potential DoS on slow operations

Security Strengths

Automatic HTTPS with Let's Encrypt on all custom domains
Global CDN with built-in DDoS protection at edge
Deploy Preview access control with password protection option
Netlify Functions run in isolated AWS Lambda environment
Build plugins can add security checks to deployment pipeline

Step-by-Step Security Guide

1. Separate Build-Time from Runtime Variables

Netlify's build-time variables get embedded in your static output — anyone can see them. Keep all secrets as runtime-only variables that only Netlify Functions can access.

# netlify.toml — context-specific variables
[context.production.environment]
  API_SECRET = "prod-secret-here" # runtime only

[context.deploy-preview.environment]
  API_SECRET = "staging-secret-here" # different for previews

2. Add Auth to Every Netlify Function

Functions are public at /.netlify/functions/<name> with no built-in authentication. Every function must validate the caller before processing the request.

// netlify/functions/delete-account.js
exports.handler = async (event) => {
  const token = event.headers.authorization?.split('Bearer ')[1];
  if (!token) return { statusCode: 401, body: 'Unauthorized' };

  const user = await verifyToken(token);
  if (!user) return { statusCode: 401, body: 'Invalid token' };

  // Now safe to process
  await deleteUser(user.id);
  return { statusCode: 200, body: 'Deleted' };
};

3. Configure Headers via _headers File

Since Netlify serves static files from a CDN, you can't set response headers in application code. Create a _headers file in your publish directory.

# _headers (place in publish directory: public/, dist/, etc.)
/*
  X-Frame-Options: DENY
  X-Content-Type-Options: nosniff
  Strict-Transport-Security: max-age=31536000; includeSubDomains
  Content-Security-Policy: default-src 'self'; script-src 'self'
  Referrer-Policy: strict-origin-when-cross-origin

4. Isolate Deploy Contexts

Netlify has three deploy contexts: Production, Deploy Preview, and Branch Deploy. Without isolation, preview deployments use production secrets — meaning any PR can interact with production APIs.

5. Restrict Deploy Preview Access

Every PR generates a public preview URL. Use Netlify Identity or password protection to restrict access so unreleased features and staging data aren't exposed.

6. Audit Plugins and Scan

Netlify plugins run during build with access to your environment variables and filesystem. Review installed plugins, then run VAS on the deployed site to catch remaining issues.

Common Security Mistakes

Avoid these common Netlify security pitfalls:

Using secrets in build-time variables — they get embedded in static HTML/JS visible to everyone
Netlify Functions without auth — they're public endpoints at /.netlify/functions/<name>
Setting headers in application code instead of _headers file (headers won't apply to static assets)
No deploy context isolation — preview deployments use production API keys by default
Installing Netlify plugins without reviewing what environment variables they access

Known Netlify Vulnerabilities

These are documented security issues specific to Netlify applications. Click through for detailed remediation guidance.

Recommended Security Tools

Use these tools to maintain security throughout development:

VAS Security Scanner
npm audit / yarn audit
Git-secrets
Snyk

Ready to Secure Your App?

Security is an ongoing process, not a one-time checklist. After implementing these steps, use VAS to verify your Netlify app is secure before launch, and consider regular scans as you add new features.

Frequently Asked Questions

How do I add security headers on Netlify?

Create a _headers file in your publish directory (public/, dist/, build/). Unlike server platforms where you set headers in code, Netlify's CDN uses this file. You can also add headers in netlify.toml under [[headers]].

What's the difference between build and runtime variables on Netlify?

Build-time variables are available during the build process and get embedded in your static output — they're visible in the HTML/JS files. Runtime variables are only accessible inside Netlify Functions and never appear in static files. Always use runtime-only variables for secrets.