Generates security HTTP headers (CSP, HSTS, CORS, etc.) for web applications to prevent common attacks...
Generates security HTTP headers for web applications to prevent XSS, clickjacking, MITM attacks, and more.
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:
Brief overview of what will be added:
Content Security Policy (CSP):
HTTP Strict Transport Security (HSTS):
X-Frame-Options:
X-Content-Type-Options:
Referrer-Policy:
Permissions-Policy:
CORS (Cross-Origin Resource Sharing):
Based on detected framework, generate appropriate configuration:
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
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)
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;
}
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>
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
# 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',
# ...
]
Ask user about specific requirements:
CSP Customization:
CORS Customization:
Permissions Policy:
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')
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:
Using browser DevTools:
CSP Warnings:
HSTS Considerations:
CORS Warnings:
General:
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()
})
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:;
`
Document how to:
Offer different security profiles:
CSP: No unsafe-inline, no unsafe-eval
HSTS: Long max-age with preload
CORS: Specific origins only
Permissions: All restricted
CSP: Limited unsafe-inline for styling
HSTS: Standard max-age
CORS: Controlled origins
Permissions: Essential features only
CSP: Permissive for hot reload
HSTS: Disabled or short max-age
CORS: Localhost allowed
Permissions: Most allowed
// 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 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;
// 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,
}))