Claude-skill-registry cors-configuration-validator
Automatically validates Cloudflare Workers CORS configuration, ensuring proper headers, OPTIONS handling, and origin validation for cross-origin requests
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/cors-configuration-validator" ~/.claude/skills/majiayu000-claude-skill-registry-cors-configuration-validator && rm -rf "$T"
manifest:
skills/data/cors-configuration-validator/SKILL.mdsource content
CORS Configuration Validator SKILL
Activation Patterns
This SKILL automatically activates when:
objects are creatednew Response()- CORS-related headers are set or modified
- API endpoints that serve cross-origin requests
- OPTIONS method handling is detected
- Cross-origin request patterns are identified
Expertise Provided
Workers-Specific CORS Validation
- Header Validation: Ensures all required CORS headers are present
- OPTIONS Handling: Validates preflight request handling
- Origin Validation: Checks for proper origin validation logic
- Method Validation: Ensures correct allowed methods
- Header Validation: Validates allowed headers configuration
- Security: Prevents overly permissive CORS configurations
Specific Checks Performed
❌ CORS Anti-Patterns
// These patterns trigger immediate alerts: // Missing CORS headers export default { async fetch(request: Request, env: Env) { return new Response(JSON.stringify(data)); // Browsers will block cross-origin requests! } } // Overly permissive for authenticated APIs const corsHeaders = { 'Access-Control-Allow-Origin': '*', // ANY origin can call! 'Access-Control-Allow-Credentials': 'true' // With credentials! };
✅ CORS Best Practices
// These patterns are validated as correct: // Proper CORS with origin validation function getCorsHeaders(origin: string) { const allowedOrigins = ['https://app.example.com', 'https://example.com']; const allowOrigin = allowedOrigins.includes(origin) ? origin : allowedOrigins[0]; return { 'Access-Control-Allow-Origin': allowOrigin, 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', 'Access-Control-Max-Age': '86400', }; } export default { async fetch(request: Request, env: Env) { const origin = request.headers.get('Origin') || ''; if (request.method === 'OPTIONS') { return new Response(null, { headers: getCorsHeaders(origin) }); } const response = new Response(JSON.stringify(data)); Object.entries(getCorsHeaders(origin)).forEach(([k, v]) => { response.headers.set(k, v); }); return response; } }
Integration Points
Complementary to Existing Components
- cloudflare-security-checker SKILL: Handles overall security, SKILL focuses specifically on CORS
- workers-runtime-validator SKILL: Ensures runtime compatibility, SKILL validates CORS patterns
- edge-performance-oracle SKILL: Handles performance, SKILL ensures CORS doesn't impact performance
Escalation Triggers
- Complex CORS architecture questions →
agentcloudflare-security-sentinel - Advanced authentication with CORS →
agentcloudflare-security-sentinel - CORS troubleshooting →
agentcloudflare-security-sentinel
Validation Rules
P1 - Critical (Will Break Cross-Origin Requests)
- Missing CORS Headers: No CORS headers on API responses
- Missing OPTIONS Handler: No preflight request handling
- Invalid Header Combinations: Conflicting CORS header combinations
P2 - High (Security Risk)
- Overly Permissive Origin:
with credentialsAccess-Control-Allow-Origin: * - Wildcard Methods:
with sensitive operationsAccess-Control-Allow-Methods: * - Missing Origin Validation: Accepting any origin without validation
P3 - Medium (Best Practices)
- Missing Cache Headers: No
for preflight cachingAccess-Control-Max-Age - Incomplete Headers: Missing some optional but recommended headers
- Hardcoded Origins: Origins not easily configurable
Remediation Examples
Fixing Missing CORS Headers
// ❌ Critical: No CORS headers (browsers block requests) export default { async fetch(request: Request, env: Env) { const data = { message: 'Hello from API' }; return new Response(JSON.stringify(data), { headers: { 'Content-Type': 'application/json' } // Missing CORS headers! }); } } // ✅ Correct: Complete CORS implementation function getCorsHeaders(origin: string) { const allowedOrigins = ['https://app.example.com', 'https://example.com']; const allowOrigin = allowedOrigins.includes(origin) ? origin : allowedOrigins[0]; return { 'Access-Control-Allow-Origin': allowOrigin, 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', 'Access-Control-Max-Age': '86400', }; } export default { async fetch(request: Request, env: Env) { const origin = request.headers.get('Origin') || ''; // Handle preflight requests if (request.method === 'OPTIONS') { return new Response(null, { headers: getCorsHeaders(origin) }); } const data = { message: 'Hello from API' }; return new Response(JSON.stringify(data), { headers: { 'Content-Type': 'application/json', ...getCorsHeaders(origin) } }); } }
Fixing Overly Permissive CORS
// ❌ High: Overly permissive for authenticated API export default { async fetch(request: Request, env: Env) { const corsHeaders = { 'Access-Control-Allow-Origin': '*', // ANY origin! 'Access-Control-Allow-Credentials': 'true', // With credentials! 'Access-Control-Allow-Methods': '*', // ANY method! }; // This allows any website to make authenticated requests! return new Response('Sensitive data', { headers: corsHeaders }); } } // ✅ Correct: Secure CORS for authenticated API function getSecureCorsHeaders(origin: string) { const allowedOrigins = [ 'https://app.example.com', 'https://admin.example.com', 'https://example.com' ]; // Only allow known origins const allowOrigin = allowedOrigins.includes(origin) ? origin : allowedOrigins[0]; return { 'Access-Control-Allow-Origin': allowOrigin, 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE', // Specific methods 'Access-Control-Allow-Headers': 'Content-Type, Authorization', 'Access-Control-Allow-Credentials': 'true', 'Access-Control-Max-Age': '86400', }; } export default { async fetch(request: Request, env: Env) { const origin = request.headers.get('Origin') || ''; // Verify authentication const authHeader = request.headers.get('Authorization'); if (!authHeader || !isValidAuth(authHeader)) { return new Response('Unauthorized', { status: 401 }); } return new Response('Sensitive data', { headers: getSecureCorsHeaders(origin) }); } }
Fixing Missing OPTIONS Handler
// ❌ Critical: No OPTIONS handling (preflight fails) export default { async fetch(request: Request, env: Env) { if (request.method === 'POST') { // Handle POST request return new Response('POST handled'); } return new Response('Method not allowed', { status: 405 }); } } // ✅ Correct: Proper OPTIONS handling export default { async fetch(request: Request, env: Env) { const origin = request.headers.get('Origin') || ''; // Handle preflight requests if (request.method === 'OPTIONS') { return new Response(null, { headers: { 'Access-Control-Allow-Origin': origin, 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', 'Access-Control-Max-Age': '86400', } }); } if (request.method === 'POST') { return new Response('POST handled', { headers: { 'Access-Control-Allow-Origin': origin, } }); } return new Response('Method not allowed', { status: 405 }); } }
Fixing Dynamic CORS for Different Environments
// ❌ Medium: Hardcoded origins (not flexible) function getCorsHeaders() { return { 'Access-Control-Allow-Origin': 'https://app.example.com', // Hardcoded 'Access-Control-Allow-Methods': 'GET, POST', }; } // ✅ Correct: Configurable and secure CORS function getCorsHeaders(origin: string, env: Env) { // Get allowed origins from environment const allowedOrigins = (env.ALLOWED_ORIGINS || 'https://app.example.com') .split(',') .map(o => o.trim()); const allowOrigin = allowedOrigins.includes(origin) ? origin : allowedOrigins[0]; return { 'Access-Control-Allow-Origin': allowOrigin, 'Access-Control-Allow-Methods': env.ALLOWED_METHODS || 'GET, POST, PUT, DELETE', 'Access-Control-Allow-Headers': env.ALLOWED_HEADERS || 'Content-Type, Authorization', 'Access-Control-Max-Age': '86400', }; } export default { async fetch(request: Request, env: Env) { const origin = request.headers.get('Origin') || ''; if (request.method === 'OPTIONS') { return new Response(null, { headers: getCorsHeaders(origin, env) }); } return new Response('Response', { headers: getCorsHeaders(origin, env) }); } }
CORS Header Reference
Essential Headers
{ 'Access-Control-Allow-Origin': 'https://example.com', // Required 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', // Required for preflight 'Access-Control-Allow-Headers': 'Content-Type, Authorization', // Required for preflight }
Optional but Recommended Headers
{ 'Access-Control-Max-Age': '86400', // Cache preflight for 24 hours 'Access-Control-Allow-Credentials': 'true', // For cookies/auth 'Vary': 'Origin', // Important for caching with multiple origins }
Security Considerations
// ❌ Don't do this for authenticated APIs: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true' } // ✅ Do this instead: { 'Access-Control-Allow-Origin': 'https://app.example.com', // Specific origin 'Access-Control-Allow-Credentials': 'true' }
MCP Server Integration
When Cloudflare MCP server is available:
- Query latest CORS best practices and security recommendations
- Get current browser CORS specification updates
- Check for common CORS vulnerabilities and mitigations
Benefits
Immediate Impact
- Prevents CORS Errors: Catches missing headers before deployment
- Improves Security: Prevents overly permissive CORS configurations
- Better User Experience: Ensures cross-origin requests work properly
Long-term Value
- Consistent CORS Standards: Ensures all APIs follow proper CORS patterns
- Reduced Debugging Time: Immediate feedback on CORS issues
- Security Compliance: Prevents CORS-related security vulnerabilities
Usage Examples
During Response Creation
// Developer types: new Response(data) // SKILL immediately activates: "⚠️ HIGH: Response missing CORS headers. Cross-origin requests will be blocked by browsers."
During API Development
// Developer types: 'Access-Control-Allow-Origin': '*' // SKILL immediately activates: "⚠️ HIGH: Overly permissive CORS with wildcard origin. Consider specific origins for security."
During Method Handling
// Developer types: if (request.method === 'POST') { ... } // SKILL immediately activates: "⚠️ HIGH: Missing OPTIONS handler for preflight requests. Add OPTIONS method handling."
CORS Checklist
Required for Cross-Origin Requests
-
header setAccess-Control-Allow-Origin - OPTIONS method handled for preflight requests
-
header for preflightAccess-Control-Allow-Methods -
header for preflightAccess-Control-Allow-Headers
Security Best Practices
- Origin validation (not wildcard for authenticated APIs)
- Specific allowed methods (not wildcard)
- Proper credentials handling
- Environment-based origin configuration
Performance Optimization
-
header setAccess-Control-Max-Age -
header for cachingVary: Origin - Efficient preflight handling
This SKILL ensures CORS is configured correctly by providing immediate, autonomous validation of CORS patterns, preventing common cross-origin issues and security vulnerabilities.