UNPKG

vibe-guard

Version:

🛡️ Vibe-Guard Security Scanner - Catch security issues before they catch you!

61 lines 3.46 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.OpenCorsRule = void 0; const types_1 = require("../types"); class OpenCorsRule extends types_1.BaseRule { constructor() { super(...arguments); this.name = 'open-cors'; this.description = 'Detects overly permissive CORS configurations'; this.severity = 'high'; this.corsPatterns = [ // Wildcard CORS origins { pattern: /Access-Control-Allow-Origin\s*:\s*['"`]\*['"`]/gi, message: 'Wildcard CORS origin allows any domain' }, { pattern: /cors\(\s*\{\s*origin\s*:\s*['"`]\*['"`]/gi, message: 'CORS middleware configured with wildcard origin' }, { pattern: /\.header\s*\(\s*['"`]Access-Control-Allow-Origin['"`]\s*,\s*['"`]\*['"`]/gi, message: 'Manual CORS header set to wildcard' }, // Express CORS middleware with wildcard { pattern: /app\.use\s*\(\s*cors\s*\(\s*\{\s*origin\s*:\s*true/gi, message: 'CORS origin set to true (allows all origins)' }, { pattern: /app\.use\s*\(\s*cors\s*\(\s*\)\s*\)/gi, message: 'CORS middleware used without origin restrictions' }, // Permissive credentials { pattern: /Access-Control-Allow-Credentials\s*:\s*['"`]true['"`]/gi, message: 'CORS credentials enabled - ensure origin is restricted' }, // Overly broad methods { pattern: /Access-Control-Allow-Methods\s*:\s*['"`]\*['"`]/gi, message: 'CORS allows all HTTP methods' }, { pattern: /Access-Control-Allow-Headers\s*:\s*['"`]\*['"`]/gi, message: 'CORS allows all headers' }, // Framework-specific patterns { pattern: /@CrossOrigin\s*\(\s*origins\s*=\s*['"`]\*['"`]/gi, message: 'Spring @CrossOrigin annotation with wildcard origin' }, { pattern: /enable_cors\s*\(\s*origins\s*=\s*\[\s*['"`]\*['"`]/gi, message: 'FastAPI CORS with wildcard origin' } ]; this.safePatterns = [ /localhost/i, /127\.0\.0\.1/, /\.local/i, /development/i, /staging/i, /test/i ]; } check(fileContent) { const issues = []; for (const { pattern, message } of this.corsPatterns) { const matches = this.findMatches(fileContent.content, pattern); for (const { line, column, lineContent } of matches) { // Skip if it's in a development/test context if (this.isDevelopmentContext(fileContent.content, line)) { continue; } issues.push(this.createIssue(fileContent.path, line, column, lineContent, `Permissive CORS configuration: ${message}`, `Restrict CORS origins to specific domains. Use specific origins like 'https://yourdomain.com' instead of '*'. Consider using environment variables for different environments.`)); } } return issues; } isDevelopmentContext(content, lineNumber) { const lines = content.split('\n'); const contextRange = 5; const startLine = Math.max(0, lineNumber - contextRange - 1); const endLine = Math.min(lines.length, lineNumber + contextRange); const contextLines = lines.slice(startLine, endLine).join('\n'); return this.safePatterns.some(pattern => pattern.test(contextLines)); } } exports.OpenCorsRule = OpenCorsRule; //# sourceMappingURL=open-cors.js.map