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 Strengths
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 previews2. 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-origin4. 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:
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:
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.