How to Secure Your Netlify App
Last updated: April 20, 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 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:
- 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:
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.
Explore Related Resources
Related Guides
Related Vulnerabilities
More on Netlify Security
Every angle of Netlify security, from the specific findings we detect to step-by-step fixes.
Netlify Security Scanner
Hub page: scan your Netlify app for vulnerabilities.
Netlify Security Risks
Specific risks we find in Netlify apps, with real-world examples.
Netlify Security Issues
Issues grouped by severity with detection and fix steps.
Netlify Best Practices
Remediation playbook derived from Netlify's actual failure modes.
Is Netlify Safe?
Honest assessment of Netlify's production readiness.
Netlify Security Checklist
Pre-launch checklist covering every finding class for Netlify.
Can Netlify Apps Be Hacked?
Attack vectors specific to Netlify and how they get exploited.
What People Say About Netlify Security
Community sentiment on Netlify security, compared with our scan data.