Security Header Generator
Generates security HTTP headers for web applications to prevent XSS, clickjacking, MITM attacks, and more.
When to Use
-
"Add security headers to my app"
-
"Setup Content Security Policy"
-
"Configure CORS headers"
-
"Enable HSTS"
-
"Secure my application headers"
-
"Prevent clickjacking"
-
"Setup security headers for Express/Next.js/nginx"
Instructions
- Detect Application Type
Scan the project to identify:
Check for various frameworks/servers
[ -f "package.json" ] && echo "Node.js project" [ -f "next.config.js" ] && echo "Next.js" [ -f ".htaccess" ] && echo "Apache" [ -f "nginx.conf" ] && echo "nginx" [ -f "app.py" ] && echo "Python/Flask" [ -f "Startup.cs" ] && echo ".NET"
Present findings:
-
Project type detected
-
Current security headers (if any)
-
Recommended headers based on app type
- Explain Security Headers
Brief overview of what will be added:
Content Security Policy (CSP):
-
Prevents XSS attacks
-
Controls resource loading sources
-
Mitigates data injection attacks
HTTP Strict Transport Security (HSTS):
-
Forces HTTPS connections
-
Prevents protocol downgrade attacks
-
Protects against MITM attacks
X-Frame-Options:
-
Prevents clickjacking
-
Controls iframe embedding
-
Protects against UI redress attacks
X-Content-Type-Options:
-
Prevents MIME-sniffing
-
Blocks content-type confusion attacks
Referrer-Policy:
-
Controls referrer information leakage
-
Protects user privacy
Permissions-Policy:
-
Controls browser features
-
Limits API access (camera, microphone, etc.)
CORS (Cross-Origin Resource Sharing):
-
Controls cross-origin requests
-
Prevents unauthorized API access
- Generate Headers Configuration
Based on detected framework, generate appropriate configuration:
Framework-Specific Configurations
Next.js
Create or update next.config.js :
/** @type {import('next').NextConfig} */ const securityHeaders = [ { key: 'Content-Security-Policy', value: ContentSecurityPolicy.replace(/\n/g, ''), }, { key: 'X-DNS-Prefetch-Control', value: 'on', }, { key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload', }, { key: 'X-Frame-Options', value: 'SAMEORIGIN', }, { key: 'X-Content-Type-Options', value: 'nosniff', }, { key: 'X-XSS-Protection', value: '1; mode=block', }, { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin', }, { key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()', }, ]
// Content Security Policy
const ContentSecurityPolicy = default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests;
const nextConfig = { async headers() { return [ { source: '/:path*', headers: securityHeaders, }, ] }, }
module.exports = nextConfig
Express.js
Install helmet middleware:
npm install helmet
Configure in main app file:
const express = require('express') const helmet = require('helmet')
const app = express()
// Use Helmet middleware app.use(helmet({ contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], scriptSrc: ["'self'", "'unsafe-inline'"], styleSrc: ["'self'", "'unsafe-inline'"], imgSrc: ["'self'", "data:", "https:"], fontSrc: ["'self'", "data:"], objectSrc: ["'none'"], baseUri: ["'self'"], formAction: ["'self'"], frameAncestors: ["'none'"], upgradeInsecureRequests: [], }, }, hsts: { maxAge: 63072000, includeSubDomains: true, preload: true, }, frameguard: { action: 'sameorigin', }, xssFilter: true, noSniff: true, referrerPolicy: { policy: 'strict-origin-when-cross-origin', }, permissionsPolicy: { features: { camera: ["'none'"], microphone: ["'none'"], geolocation: ["'none'"], }, }, }))
// CORS configuration (if needed) const cors = require('cors') app.use(cors({ origin: process.env.ALLOWED_ORIGINS?.split(',') || 'http://localhost:3000', credentials: true, methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], allowedHeaders: ['Content-Type', 'Authorization'], }))
app.listen(3000)
nginx
Create or update nginx configuration:
Security headers configuration
Add this to your server block or http block
server { listen 443 ssl http2; server_name example.com;
# SSL configuration
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
# Security Headers
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
# Content Security Policy
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests;" always;
# CORS (if needed)
add_header Access-Control-Allow-Origin "$http_origin" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;
add_header Access-Control-Allow-Credentials "true" always;
# Handle OPTIONS preflight
if ($request_method = 'OPTIONS') {
return 204;
}
location / {
# Your app configuration
proxy_pass http://localhost:3000;
}
}
Redirect HTTP to HTTPS
server { listen 80; server_name example.com; return 301 https://$server_name$request_uri; }
Apache (.htaccess)
Create or update .htaccess :
Security Headers
Force HTTPS
<IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] </IfModule>
HTTP Strict Transport Security
<IfModule mod_headers.c> Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" </IfModule>
X-Frame-Options
<IfModule mod_headers.c> Header always set X-Frame-Options "SAMEORIGIN" </IfModule>
X-Content-Type-Options
<IfModule mod_headers.c> Header always set X-Content-Type-Options "nosniff" </IfModule>
X-XSS-Protection
<IfModule mod_headers.c> Header always set X-XSS-Protection "1; mode=block" </IfModule>
Referrer Policy
<IfModule mod_headers.c> Header always set Referrer-Policy "strict-origin-when-cross-origin" </IfModule>
Permissions Policy
<IfModule mod_headers.c> Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()" </IfModule>
Content Security Policy
<IfModule mod_headers.c> Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests;" </IfModule>
CORS (if needed)
<IfModule mod_headers.c> Header always set Access-Control-Allow-Origin "*" Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" Header always set Access-Control-Allow-Headers "Authorization, Content-Type" </IfModule>
Flask/Python
from flask import Flask from flask_talisman import Talisman
app = Flask(name)
Configure security headers with Talisman
csp = { 'default-src': "'self'", 'script-src': ["'self'", "'unsafe-inline'", "'unsafe-eval'"], 'style-src': ["'self'", "'unsafe-inline'"], 'img-src': ["'self'", "data:", "https:"], 'font-src': ["'self'", "data:"], 'object-src': "'none'", 'base-uri': "'self'", 'form-action': "'self'", 'frame-ancestors': "'none'", 'upgrade-insecure-requests': True, }
Talisman(app, force_https=True, strict_transport_security=True, strict_transport_security_max_age=63072000, strict_transport_security_include_subdomains=True, content_security_policy=csp, content_security_policy_nonce_in=['script-src'], frame_options='SAMEORIGIN', frame_options_allow_from=None, referrer_policy='strict-origin-when-cross-origin', x_content_type_options=True, x_xss_protection=True, )
CORS configuration (if needed)
from flask_cors import CORS
CORS(app, origins=["http://localhost:3000"], methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"], allow_headers=["Content-Type", "Authorization"], supports_credentials=True, )
@app.route('/') def index(): return 'Hello with secure headers!'
if name == 'main': app.run()
Install dependencies:
pip install flask-talisman flask-cors
Django
settings.py
Security Headers Middleware (built-in)
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', # ... other middleware ]
Security Settings
SECURE_SSL_REDIRECT = True SECURE_HSTS_SECONDS = 63072000 SECURE_HSTS_INCLUDE_SUBDOMAINS = True SECURE_HSTS_PRELOAD = True
SECURE_CONTENT_TYPE_NOSNIFF = True SECURE_BROWSER_XSS_FILTER = True
X_FRAME_OPTIONS = 'SAMEORIGIN'
SECURE_REFERRER_POLICY = 'strict-origin-when-cross-origin'
Content Security Policy (use django-csp package)
pip install django-csp
CSP_DEFAULT_SRC = ("'self'",) CSP_SCRIPT_SRC = ("'self'", "'unsafe-inline'", "'unsafe-eval'") CSP_STYLE_SRC = ("'self'", "'unsafe-inline'") CSP_IMG_SRC = ("'self'", "data:", "https:") CSP_FONT_SRC = ("'self'", "data:") CSP_OBJECT_SRC = ("'none'",) CSP_BASE_URI = ("'self'",) CSP_FORM_ACTION = ("'self'",) CSP_FRAME_ANCESTORS = ("'none'",) CSP_UPGRADE_INSECURE_REQUESTS = True
CORS (use django-cors-headers package)
pip install django-cors-headers
CORS_ALLOWED_ORIGINS = [ "http://localhost:3000", "http://localhost:8000", ] CORS_ALLOW_CREDENTIALS = True CORS_ALLOW_METHODS = [ 'DELETE', 'GET', 'OPTIONS', 'PATCH', 'POST', 'PUT', ] CORS_ALLOW_HEADERS = [ 'accept', 'authorization', 'content-type', ]
Add to MIDDLEWARE:
MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'csp.middleware.CSPMiddleware', 'django.middleware.security.SecurityMiddleware', # ... ]
- Customize for Project Needs
Ask user about specific requirements:
CSP Customization:
-
External scripts needed? (Google Analytics, CDN scripts)
-
Inline styles required? (styled-components, CSS-in-JS)
-
Image CDNs or external sources?
-
Font providers (Google Fonts)?
-
API endpoints for fetch requests?
CORS Customization:
-
Which origins should be allowed?
-
Credentials needed? (cookies, authorization headers)
-
Which HTTP methods?
-
Custom headers required?
Permissions Policy:
-
Camera access needed?
-
Geolocation required?
-
Microphone usage?
-
Payment APIs?
- Generate Test Suite
Create test file to verify headers:
// test-security-headers.js const https = require('https')
function testSecurityHeaders(url) { https.get(url, (res) => { console.log('Security Headers Test:\n')
const requiredHeaders = {
'strict-transport-security': 'HSTS',
'x-frame-options': 'Clickjacking Protection',
'x-content-type-options': 'MIME Sniffing Protection',
'content-security-policy': 'CSP',
'referrer-policy': 'Referrer Policy',
'permissions-policy': 'Permissions Policy',
}
for (const [header, name] of Object.entries(requiredHeaders)) {
const value = res.headers[header]
if (value) {
console.log(`✅ ${name}: ${value}`)
} else {
console.log(`❌ ${name}: MISSING`)
}
}
}) }
testSecurityHeaders('https://your-domain.com')
- Provide Testing Instructions
Show how to test headers:
Using curl:
Test all headers
curl -I https://your-domain.com
Test specific header
curl -I https://your-domain.com | grep -i strict-transport-security
Using online tools:
-
Security Headers: https://securityheaders.com/
-
Mozilla Observatory: https://observatory.mozilla.org/
-
SSL Labs: https://www.ssllabs.com/ssltest/
Using browser DevTools:
-
Open DevTools (F12)
-
Go to Network tab
-
Reload page
-
Click on first request
-
Check "Response Headers" section
- Document Warnings and Considerations
CSP Warnings:
-
'unsafe-inline' reduces security - remove if possible
-
'unsafe-eval' allows eval() - avoid if not needed
-
Test thoroughly - CSP can break functionality
-
Use CSP report-only mode first
HSTS Considerations:
-
Can't easily undo once set
-
Test on staging first
-
Consider shorter max-age initially
-
HSTS preload is permanent
CORS Warnings:
-
Wildcard (*) allows all origins - use specific origins
-
credentials + wildcard not allowed
-
Preflight requests add latency
General:
-
Headers may break third-party integrations
-
Test all functionality after adding
-
Monitor for CSP violations
-
Update CSP as app evolves
- Setup CSP Reporting
Offer to set up CSP violation reporting:
// CSP with report URI
const ContentSecurityPolicy = default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; report-uri /csp-violation-report; report-to csp-endpoint;
// Express endpoint to receive reports app.post('/csp-violation-report', express.json({ type: 'application/csp-report' }), (req, res) => { console.log('CSP Violation:', req.body) // Log to monitoring service res.status(204).end() })
- Create Environment-Specific Configs
Suggest different headers for dev vs production:
// next.config.js const isDev = process.env.NODE_ENV === 'development'
const ContentSecurityPolicy = isDev
? default-src 'self' 'unsafe-eval' 'unsafe-inline'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline';
: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data: https:;
- Provide Maintenance Guide
Document how to:
-
Add new external sources to CSP
-
Update CORS origins
-
Adjust security levels
-
Handle CSP violations
-
Test changes safely
Security Level Presets
Offer different security profiles:
Strict (Recommended for Production)
CSP: No unsafe-inline, no unsafe-eval HSTS: Long max-age with preload CORS: Specific origins only Permissions: All restricted
Moderate (Balance Security/Functionality)
CSP: Limited unsafe-inline for styling HSTS: Standard max-age CORS: Controlled origins Permissions: Essential features only
Relaxed (Development)
CSP: Permissive for hot reload HSTS: Disabled or short max-age CORS: Localhost allowed Permissions: Most allowed
Common Patterns
API Server Headers
// API doesn't need all headers app.use(helmet({ contentSecurityPolicy: false, // No HTML content xssFilter: false, // No HTML rendering hsts: { maxAge: 63072000, includeSubDomains: true, }, }))
// Strict CORS for APIs app.use(cors({ origin: function(origin, callback) { const allowedOrigins = process.env.ALLOWED_ORIGINS.split(',') if (!origin || allowedOrigins.includes(origin)) { callback(null, true) } else { callback(new Error('Not allowed by CORS')) } }, credentials: true, }))
Static Site Headers
Static HTML/CSS/JS site
add_header Content-Security-Policy "default-src 'self'; img-src 'self' data: https:; font-src 'self' data:; style-src 'self' 'unsafe-inline';" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always;
SPA with API Headers
// Frontend SPA headers (Next.js) const securityHeaders = [ { key: 'Content-Security-Policy', value: "default-src 'self'; connect-src 'self' https://api.example.com; script-src 'self' 'unsafe-inline' 'unsafe-eval';", }, // ... other headers ]
// Separate API server (Express) app.use(cors({ origin: ['https://app.example.com', 'https://www.example.com'], credentials: true, }))
Best Practices
-
✅ Start with report-only CSP, then enforce
-
✅ Test headers on staging before production
-
✅ Use environment variables for origins
-
✅ Monitor CSP violations in production
-
✅ Regular security header audits
-
✅ Keep HSTS max-age reasonable initially
-
✅ Document all header decisions
-
✅ Version control security configs