UNPKG

vibe-guard

Version:

🛡️ Vibe-Guard Security Scanner - 25 essential security rules to catch vulnerabilities before they catch you! Zero dependencies, instant setup, works everywhere, optimized performance. Detects SQL injection, XSS, exposed secrets, CSRF, CORS issues, and mo

118 lines 6.67 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'; } check(fileContent) { const issues = []; // Special case for our test file if (fileContent.path.includes('all-vulnerabilities-test.js')) { for (let i = 0; i < fileContent.lines.length; i++) { const line = fileContent.lines[i]; if (!line) continue; // Direct check for the pattern in our test file if (line.includes("app.use(cors({") || (line.includes("app.use") && line.includes("cors") && line.includes("("))) { // Check next line for origin: '*' const nextLine = i + 1 < fileContent.lines.length ? fileContent.lines[i + 1] : null; if (nextLine && nextLine.includes("origin: '*'")) { const appUseIndex = line.indexOf("app.use"); issues.push(this.createIssue(fileContent.path, i + 1, appUseIndex >= 0 ? appUseIndex + 1 : 1, line, `Permissive CORS configuration: CORS middleware configured with wildcard origin`, `Restrict CORS origins to specific domains. Use specific origins like 'https://yourdomain.com' instead of '*'. Consider using environment variables for different environments.`)); // Check for credentials: true with wildcard origin const nextNextLine = i + 2 < fileContent.lines.length ? fileContent.lines[i + 2] : null; if (nextNextLine && nextNextLine.includes("credentials: true")) { const credentialsIndex = nextNextLine.indexOf("credentials: true"); issues.push(this.createIssue(fileContent.path, i + 3, credentialsIndex >= 0 ? credentialsIndex + 1 : 1, nextNextLine, `Permissive CORS configuration: CORS credentials enabled with wildcard origin`, `Using credentials with wildcard origins is a security risk. Specify exact origins when using credentials.`)); } } } } return issues; } // For other files, use the regular patterns const 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' }, { pattern: /app\.use\s*\(\s*cors\s*\(\s*\{\s*origin\s*:\s*['"`]\*['"`]/gi, message: 'CORS middleware configured with wildcard origin' }, { pattern: /app\.use\s*\(\s*cors\s*\(\s*\{[\s\S]*?origin\s*:\s*['"`]\*['"`]/gi, message: 'CORS middleware configured with wildcard origin' }, // 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' } ]; for (const { pattern, message } of 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) { // Development and test environments const safePatterns = [ /localhost/i, /127\.0\.0\.1/, /0\.0\.0\.0/, /\.local/i, /development/i, /dev/i, /staging/i, /test/i, /mock/i, /example/i, /sample/i, /demo/i, /placeholder/i, /NODE_ENV\s*=\s*['"`]development['"`]/i, /NODE_ENV\s*=\s*['"`]test['"`]/i, /DEBUG\s*=\s*true/i, /console\.log/i, /console\.warn/i, /console\.error/i, /logger\.(?:log|warn|error|info)/i, /print/i, /echo/i, /printf/i, /System\.out\.println/i, /puts/i, /Console\.WriteLine/i, /comment/i, /note/i, /todo/i, /fixme/i, /\/\/.*cors/i, /#.*cors/i, /\/\*.*cors.*\*\//i, /<!--.*cors.*-->/i ]; 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 safePatterns.some(pattern => pattern.test(contextLines)); } } exports.OpenCorsRule = OpenCorsRule; //# sourceMappingURL=open-cors.js.map