Configure HTTP Security Headers for Web Applications
A skill for configuring HTTP security headers - CSP, HSTS, clickjacking protection - across Nginx, Apache, Express, and Django.
Maintainer of this project? Claim this page to edit the listing.
1.0.0Add to Favorites
Why it matters
Implement and configure comprehensive HTTP security headers across web servers and application frameworks to protect against XSS, CSRF, clickjacking, and content injection attacks using defense-in-depth strategies.
Outcomes
What it gets done
Configure Content Security Policy (CSP) with progressive enhancement from report-only to strict enforcement
Set up HSTS, X-Frame-Options, and anti-sniffing headers in Nginx, Apache, or application middleware
Implement CSP violation reporting endpoints to monitor and refine security policies
Test and validate security header configurations across browsers using automated tools and manual inspection
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/vb-security-header-config | bash Overview
Security Header Configuration Expert
This skill configures HTTP security headers - CSP, HSTS, X-Frame-Options, and CSP violation reporting - with working examples for Nginx, Apache, Express.js/Helmet, and Django. Use it when configuring or hardening HTTP security headers for a web application at the server, framework, or application level.
What it does
A skill acting as an expert in HTTP security headers configuration, covering defense against XSS, CSRF, clickjacking, and content injection through properly layered security headers. It documents defense-in-depth principles (layering multiple headers at both web-server and application levels, progressive enhancement starting permissive and tightening over time, testing in report-only mode before enforcement) and browser-compatibility considerations (understanding directive support, fallbacks for older browsers, mobile limitations). It provides concrete configuration for the essential headers: Content-Security-Policy (a basic policy plus a progressive report-only-then-strict rollout), X-Frame-Options versus the modern CSP frame-ancestors directive for clickjacking prevention, and Strict-Transport-Security including the preload flag. It gives working configuration examples across five layers: Nginx add_header blocks, Apache Header directives (including unsetting Server and X-Powered-By to remove server fingerprinting), Express.js via the Helmet middleware, Django settings.py (SECURE_* and CSP_* settings), and a CSP violation-report endpoint that logs blocked-uri and violated-directive fields from incoming reports. It also covers testing headers with curl and public tools (securityheaders.com, observatory.mozilla.org, hstspreload.org), a CSP rollout strategy (report-only first, monitor violations for 1-2 weeks, tighten gradually, prefer nonces over unsafe-inline/unsafe-eval), performance tips (minimize header size, strict-dynamic, unsafe-hashes over unsafe-inline), common pitfalls (conflicting X-Frame-Options vs CSP frame-ancestors, HSTS preload risk, includeSubDomains implications), and environment-specific CSP examples for development, staging, and production.
When to use - and when NOT to
Use it when configuring or hardening HTTP security headers for a web application - implementing CSP, HSTS, clickjacking protection, or setting up violation reporting - at the web-server, framework, or application level. It also covers removing server-fingerprinting headers like Server and X-Powered-By, and choosing between X-Frame-Options and the more modern CSP frame-ancestors directive for the same clickjacking-prevention goal.
Inputs and outputs
Given a web application's stack (Nginx, Apache, Express.js, or Django) and security requirements, it produces working header configuration blocks, a CSP rollout plan, and a violation-reporting endpoint implementation.
Integrations
Configuration for Nginx and Apache web servers, the Helmet middleware for Express.js, and Django's built-in SECURE_* and CSP_* settings - plus curl and third-party header-testing services (securityheaders.com, observatory.mozilla.org, hstspreload.org) for validation.
Who it's for
Web developers and security engineers hardening an application's HTTP response headers who want copy-pasteable, environment-aware configuration (development, staging, production) across common web servers and frameworks, plus a safe, monitored rollout strategy for tightening CSP without breaking legitimate resources - starting in report-only mode, watching violation reports for one to two weeks, and only then moving to full enforcement.
Source README
Security Header Configuration Expert
You are an expert in HTTP security headers configuration and implementation. You have deep knowledge of web security vulnerabilities, defense mechanisms, and how to properly configure security headers to protect web applications from attacks like XSS, CSRF, clickjacking, and content injection.
Core Security Header Principles
Defense in Depth
- Layer multiple security headers for comprehensive protection
- Configure headers at both web server and application levels
- Implement progressive enhancement, starting with permissive policies and tightening over time
- Test headers in report-only mode before enforcement
Browser Compatibility
- Understand browser support for different header directives
- Provide fallback mechanisms for older browsers
- Consider mobile browser limitations
- Test across different user agents
Essential Security Headers
Content Security Policy (CSP)
### Basic CSP implementation
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://apis.google.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';
### Progressive enhancement approach
### Step 1: Report-only mode
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report-endpoint
### Step 2: Strict policy
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self'; connect-src 'self'; font-src 'self'; base-uri 'self'; form-action 'self';
X-Frame-Options and Frame Ancestors
### Prevent clickjacking
X-Frame-Options: DENY
### Alternative: SAMEORIGIN for same-origin framing
X-Frame-Options: SAMEORIGIN
### Modern CSP approach (preferred)
Content-Security-Policy: frame-ancestors 'none';
### Or for same-origin
Content-Security-Policy: frame-ancestors 'self';
Strict Transport Security (HSTS)
### Basic HSTS implementation
Strict-Transport-Security: max-age=31536000; includeSubDomains
### With preload (for HSTS preload list)
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Advanced Configuration Patterns
Nginx Configuration
server {
# Basic security headers
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options DENY always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# HSTS (only on HTTPS)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# CSP
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https://fonts.gstatic.com; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self';" always;
# Permissions Policy
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
}
Apache Configuration
<VirtualHost *:443>
# Basic security headers
Header always set X-Content-Type-Options nosniff
Header always set X-Frame-Options DENY
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
# HSTS
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# CSP
Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none';"
# Remove server information
Header unset Server
Header unset X-Powered-By
</VirtualHost>
Application-Level Implementation
Express.js with Helmet
const helmet = require('helmet');
const express = require('express');
const app = express();
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'", "https://apis.google.com"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
fontSrc: ["'self'", "https://fonts.gstatic.com"],
connectSrc: ["'self'"],
frameAncestors: ["'none'"],
baseUri: ["'self'"],
formAction: ["'self'"]
},
reportOnly: false
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true
},
frameguard: { action: 'deny' },
noSniff: true,
xssFilter: true,
referrerPolicy: { policy: 'strict-origin-when-cross-origin' }
}));
Django Configuration
### settings.py
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_BROWSER_XSS_FILTER = True
SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
X_FRAME_OPTIONS = 'DENY'
SECURE_REFERRER_POLICY = 'strict-origin-when-cross-origin'
### CSP configuration
CSP_DEFAULT_SRC = ("'self'",)
CSP_SCRIPT_SRC = ("'self'",)
CSP_STYLE_SRC = ("'self'", "'unsafe-inline'")
CSP_IMG_SRC = ("'self'", "data:", "https:")
CSP_FONT_SRC = ("'self'", "https://fonts.gstatic.com")
CSP_CONNECT_SRC = ("'self'",)
CSP_FRAME_ANCESTORS = ("'none'",)
CSP_BASE_URI = ("'self'",)
CSP_FORM_ACTION = ("'self'",)
Testing and Validation
Header Testing Tools
### Test headers with curl
curl -I -s https://example.com | grep -E "(Content-Security-Policy|X-Frame-Options|Strict-Transport-Security)"
### Test CSP with browser developer tools
### Check console for CSP violations
### Online testing tools
### - securityheaders.com
### - observatory.mozilla.org
### - hstspreload.org
CSP Reporting
// CSP violation report endpoint
app.post('/csp-report', express.json({type: 'application/csp-report'}), (req, res) => {
const report = req.body;
console.log('CSP Violation:', JSON.stringify(report, null, 2));
// Log to monitoring system
logger.warn('CSP violation detected', {
blockedURI: report['csp-report']['blocked-uri'],
violatedDirective: report['csp-report']['violated-directive'],
userAgent: req.get('User-Agent')
});
res.status(204).end();
});
Best Practices and Tips
CSP Implementation Strategy
- Start with
Content-Security-Policy-Report-Only - Monitor violation reports for 1-2 weeks
- Gradually tighten policy based on legitimate resource usage
- Use nonces for inline scripts when possible
- Avoid
unsafe-evalandunsafe-inlinein production
Performance Considerations
- Minimize header size for CSP directives
- Use
'strict-dynamic'for modern browsers - Consider using
'unsafe-hashes'instead of'unsafe-inline' - Cache headers appropriately
Common Pitfalls
- Don't set conflicting headers (X-Frame-Options vs CSP frame-ancestors)
- Test HSTS carefully before enabling preload
- Consider subdomain implications with
includeSubDomains - Monitor for false positives in CSP reports
- Update headers when adding new third-party services
Environment-Specific Configuration
### Development environment
add_header Content-Security-Policy-Report-Only "default-src 'self'; report-uri /csp-report;" always;
### Staging environment
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; report-uri /csp-report;" always;
### Production environment
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; report-uri /csp-report;" always;
FAQ
Common questions
Discussion
Questions & comments · 0
Sign In Sign in to leave a comment.