| name | security-security-headers |
| description | HTTP security headers including CSP, HSTS, X-Frame-Options, CORS, and other protective headers for web application security |
Security: Security Headers
Scope: HTTP security headers, CSP, HSTS, CORS, XSS protection
Lines: ~350
Last Updated: 2025-10-27
When to Use This Skill
Activate this skill when:
- Hardening web application security
- Preventing clickjacking, XSS, and MITM attacks
- Configuring Content Security Policy (CSP)
- Setting up CORS for APIs
- Implementing HTTPS enforcement (HSTS)
- Protecting against browser-based attacks
- Passing security audits and penetration tests
Essential Security Headers
Complete Header Configuration
from flask import Flask, make_response
app = Flask(__name__)
@app.after_request
def add_security_headers(response):
"""Apply security headers to all responses"""
response.headers['X-Frame-Options'] = 'DENY'
response.headers['X-XSS-Protection'] = '1; mode=block'
response.headers['X-Content-Type-Options'] = 'nosniff'
response.headers['Strict-Transport-Security'] = (
'max-age=31536000; includeSubDomains; preload'
)
response.headers['Content-Security-Policy'] = (
"default-src 'self'; "
"script-src 'self' https://cdn.example.com; "
"style-src 'self' 'unsafe-inline'; "
"img-src 'self' data: https:; "
"font-src 'self' https://fonts.gstatic.com; "
"connect-src 'self' https://api.example.com; "
"frame-ancestors 'none'; "
"base-uri 'self'; "
"form-action 'self';"
)
response.headers['Referrer-Policy'] = 'strict-origin-when-cross-origin'
response.headers['Permissions-Policy'] = (
'geolocation=(), microphone=(), camera=()'
)
return response
Content Security Policy (CSP)
CSP Directives
class CSPBuilder:
"""Build Content Security Policy header"""
def __init__(self):
self.directives = {
'default-src': ["'self'"],
'script-src': ["'self'"],
'style-src': ["'self'"],
'img-src': ["'self'"],
'font-src': ["'self'"],
'connect-src': ["'self'"],
'media-src': ["'self'"],
'object-src': ["'none'"],
'frame-src': ["'none'"],
'frame-ancestors': ["'none'"],
'base-uri': ["'self'"],
'form-action': ["'self'"],
'upgrade-insecure-requests': []
}
def allow_scripts_from(self, *sources):
"""Allow scripts from specific sources"""
self.directives['script-src'].extend(sources)
return self
def allow_styles_from(self, *sources):
"""Allow styles from specific sources"""
self.directives['style-src'].extend(sources)
():
.directives[].extend(sources)
():
nonce:
.directives[].append()
:
.directives[].append()
():
.directives[].append()
():
.directives[] = [endpoint]
() -> :
parts = []
directive, sources .directives.items():
sources:
parts.append()
:
parts.append(directive)
.join(parts)
csp = (CSPBuilder()
.allow_scripts_from(, )
.allow_styles_from()
.allow_images_from(, )
.report_to()
.build())
CSP with Nonces (Recommended)
import secrets
from flask import Flask, render_template, g
app = Flask(__name__)
@app.before_request
def generate_csp_nonce():
"""Generate unique nonce for each request"""
g.csp_nonce = secrets.token_urlsafe(16)
@app.after_request
def add_csp_header(response):
"""Add CSP with nonce"""
nonce = getattr(g, 'csp_nonce', None)
if nonce:
csp = (
f"default-src 'self'; "
f"script-src 'self' 'nonce-{nonce}'; "
f"style-src 'self' 'nonce-{nonce}'; "
f"object-src 'none';"
)
response.headers['Content-Security-Policy'] = csp
return response
@app.route('/')
def index():
"""Template can use nonce for inline scripts"""
return render_template('index.html', csp_nonce=g.csp_nonce)
<!DOCTYPE html>
<html>
<head>
<style nonce="{{ csp_nonce }}">
body { background: white; }
</style>
</head>
<body>
<script nonce="{{ csp_nonce }}">
console.log('This script is allowed');
</script>
</body>
</html>
CSP Violation Reporting
@app.route('/csp-violation-report', methods=['POST'])
def csp_violation():
"""Handle CSP violation reports"""
import json
report = request.get_json()
logger.warning('CSP Violation', extra={
'document_uri': report.get('document-uri'),
'violated_directive': report.get('violated-directive'),
'blocked_uri': report.get('blocked-uri'),
'source_file': report.get('source-file'),
'line_number': report.get('line-number')
})
db.insert_csp_violation(report)
return '', 204
Strict-Transport-Security (HSTS)
HSTS Configuration
response.headers['Strict-Transport-Security'] = 'max-age=31536000'
response.headers['Strict-Transport-Security'] = (
'max-age=31536000; includeSubDomains'
)
response.headers['Strict-Transport-Security'] = (
'max-age=31536000; includeSubDomains; preload'
)
response.headers['Strict-Transport-Security'] = 'max-age=0'
HTTPS Redirect Middleware
from flask import Flask, redirect, request
app = Flask(__name__)
@app.before_request
def redirect_to_https():
"""Enforce HTTPS for all requests"""
if not request.is_secure and app.config.get('FORCE_HTTPS'):
url = request.url.replace('http://', 'https://', 1)
return redirect(url, code=301)
X-Frame-Options
Clickjacking Prevention
response.headers['X-Frame-Options'] = 'DENY'
response.headers['X-Frame-Options'] = 'SAMEORIGIN'
response.headers['X-Frame-Options'] = 'ALLOW-FROM https://trusted.com'
response.headers['Content-Security-Policy'] = "frame-ancestors 'none'"
response.headers['Content-Security-Policy'] = "frame-ancestors 'self'"
response.headers['Content-Security-Policy'] = "frame-ancestors https://trusted.com"
Cross-Origin Resource Sharing (CORS)
CORS Configuration
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
CORS(app, origins=['https://example.com'])
CORS(app,
origins=['https://app1.example.com', 'https://app2.example.com'],
supports_credentials=True,
allow_headers=['Content-Type', 'Authorization'],
expose_headers=['X-Total-Count'],
max_age=3600)
@app.after_request
def add_cors_headers(response):
origin = request.headers.get('Origin')
allowed_origins = [
'https://app.example.com',
'https://admin.example.com'
]
if origin in allowed_origins:
response.headers['Access-Control-Allow-Origin'] = origin
response.headers['Access-Control-Allow-Credentials'] = 'true'
response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
response.headers['Access-Control-Max-Age'] = '3600'
return response
@app.route('/<path:path>', methods=['OPTIONS'])
def ():
,
CORS Security Considerations
@app.after_request
def vulnerable_cors(response):
origin = request.headers.get('Origin')
response.headers['Access-Control-Allow-Origin'] = origin
return response
@app.after_request
def secure_cors(response):
origin = request.headers.get('Origin')
if origin in ALLOWED_ORIGINS:
response.headers['Access-Control-Allow-Origin'] = origin
elif '*' in ALLOWED_ORIGINS and not CREDENTIALS_REQUIRED:
response.headers['Access-Control-Allow-Origin'] = '*'
return response
Other Security Headers
X-Content-Type-Options
response.headers['X-Content-Type-Options'] = 'nosniff'
Referrer-Policy
response.headers['Referrer-Policy'] = 'no-referrer'
response.headers['Referrer-Policy'] = 'origin'
response.headers['Referrer-Policy'] = 'origin-when-cross-origin'
response.headers['Referrer-Policy'] = 'strict-origin-when-cross-origin'
response.headers['Referrer-Policy'] = 'no-referrer-when-downgrade'
Permissions-Policy
response.headers['Permissions-Policy'] = (
'geolocation=(), microphone=(), camera=(), '
'payment=(), usb=(), magnetometer=(), gyroscope=()'
)
response.headers['Permissions-Policy'] = (
'geolocation=(self), camera=(self)'
)
response.headers['Permissions-Policy'] = (
'geolocation=(self "https://maps.example.com")'
)
X-XSS-Protection (Legacy)
response.headers['X-XSS-Protection'] = '1; mode=block'
Framework-Specific Implementations
FastAPI Security Headers
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from starlette.middleware.trustedhost import TrustedHostMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=['https://example.com'],
allow_credentials=True,
allow_methods=['GET', 'POST', 'PUT', 'DELETE'],
allow_headers=['*'],
)
app.add_middleware(
TrustedHostMiddleware,
allowed_hosts=['example.com', '*.example.com']
)
@app.middleware("http")
async def add_security_headers(request, call_next):
response = await call_next(request)
response.headers['X-Frame-Options'] = 'DENY'
response.headers['X-Content-Type-Options'] = 'nosniff'
response.headers['X-XSS-Protection'] = '1; mode=block'
response.headers['Strict-Transport-Security'] = (
'max-age=31536000; includeSubDomains'
)
response.headers['Content-Security-Policy'] = (
"default-src 'self'; script-src 'self' https://cdn.example.com"
)
return response
Express.js (Helmet)
const express = require('express');
const helmet = require('helmet');
const app = express();
app.use(helmet());
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "https://cdn.jsdelivr.net"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
connectSrc: ["'self'", "https://api.example.com"],
fontSrc: ["'self'", "https://fonts.gstatic.com"],
objectSrc: ["'none'"],
frameAncestors: ["'none'"],
},
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true
},
}));
Nginx Configuration
# Security headers in Nginx
server {
listen 443 ssl http2;
server_name example.com;
# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# CSP
add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://cdn.example.com" always;
# Clickjacking protection
add_header X-Frame-Options "DENY" always;
# MIME type sniffing protection
add_header X-Content-Type-Options "nosniff" always;
# XSS protection
add_header X-XSS-Protection "1; mode=block" always;
# Referrer policy
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Permissions policy
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
location / {
proxy_pass http://backend;
}
}
Testing Security Headers
Automated Testing
import requests
def test_security_headers():
"""Test if security headers are present"""
response = requests.get('https://example.com')
assert 'Strict-Transport-Security' in response.headers
assert 'X-Frame-Options' in response.headers
assert 'X-Content-Type-Options' in response.headers
assert 'Content-Security-Policy' in response.headers
hsts = response.headers['Strict-Transport-Security']
assert 'max-age=31536000' in hsts
assert 'includeSubDomains' in hsts
csp = response.headers['Content-Security-Policy']
assert "default-src 'self'" in csp
assert 'X-Powered-By' not in response.headers
Manual Testing Tools
curl -I https://example.com
http HEAD https://example.com
Security Best Practices
Security Headers Checklist
Essential Headers:
CORS Configuration:
CSP Best Practices:
General:
Level 3: Resources
Comprehensive Reference
Location: skills/security/security-headers/resources/REFERENCE.md
The REFERENCE.md file (1200+ lines) provides exhaustive coverage of:
- All major security headers (HSTS, CSP, X-Frame-Options, X-Content-Type-Options, etc.)
- Complete CSP directives reference (script-src, style-src, img-src, connect-src, etc.)
- CSP Levels 1, 2, and 3 feature comparison
- SameSite cookie attributes (Strict, Lax, None)
- Referrer-Policy options and privacy considerations
- Permissions-Policy (Feature-Policy successor)
- CORS headers configuration patterns
- Cookie security attributes and prefixes (__Secure-, __Host-)
- Attack vectors and mitigations (XSS, clickjacking, CSRF, MIME sniffing)
- Browser compatibility matrices
- Testing and validation tools
- Implementation patterns for Nginx, Apache, Express, Flask, Django, Next.js
- Security header grading criteria (Mozilla Observatory, SecurityHeaders.com)
- Advanced topics: nonce rotation, CSP for SPAs, Subresource Integrity (SRI)
Executable Scripts
Location: skills/security/security-headers/resources/scripts/
-
check_headers.py - Security headers scanner and grading tool
- Scans URLs for security headers
- Grades security posture (A+ to F)
- Analyzes header configuration and identifies issues
- Provides detailed recommendations
- Supports JSON output for CI/CD integration
- Usage:
./check_headers.py https://example.com --json
-
generate_csp.py - CSP policy generator from site crawl
- Crawls website to discover resource sources
- Generates CSP policy based on actual usage
- Supports strict mode and hash generation
- Identifies inline scripts and styles
- Provides detailed source analysis by directive
- Usage:
./generate_csp.py https://example.com --depth 3 --strict
-
test_headers.sh - Batch header testing across multiple domains
- Tests security headers across multiple URLs
- Supports batch testing from file
- Parallel execution for performance
- Multiple output formats (text, JSON, CSV)
- Header comparison across environments
- Usage:
./test_headers.sh -f domains.txt --output json
Configuration Examples
Location: skills/security/security-headers/resources/examples/
-
nginx-security-headers.conf - Production-ready Nginx configuration
- Complete security headers for all response types
- CSP policies for static sites, SPAs, and SSR applications
- HSTS with preload configuration
- Permissions-Policy feature restrictions
- Cookie security attributes
- Special configurations for API endpoints and static assets
-
apache-security-headers.htaccess - Apache .htaccess configuration
- mod_headers-based security header configuration
- CORS handling and preflight request support
- File access protection patterns
- MIME type configuration
- Cache control for static assets
- Environment-specific CSP policies
-
flask-security-headers.py - Flask middleware implementation
- Production-ready SecurityHeaders middleware class
- CSP nonce generation per request
- Per-route CSP policy decorators
- Secure cookie helper functions
- Complete working Flask application example
- Both class-based and decorator-based approaches
-
next-security-headers.ts - Next.js security headers configuration
- next.config.js static headers approach
- Middleware-based dynamic headers with nonces
- CSP nonce injection and access in components
- CSP violation report handler
- Complete examples for Server Components and Scripts
- TypeScript type definitions
All scripts are executable, include --help documentation, and follow production-ready patterns.
Related Skills
security-input-validation.md - CSP and XSS prevention
security-vulnerability-assessment.md - Testing security headers
frontend-performance.md - CSP impact on resource loading
api-error-handling.md - CORS error handling
Last Updated: 2025-10-27
Format Version: 1.0 (Atomic)