UNPKG

ubon

Version:

Security scanner for AI-generated apps (Cursor, Lovable, Windsurf, v0). Catches hardcoded secrets, prompt injection, hallucinated imports, Server Actions / Edge runtime mistakes, and the vibe-coded vulnerabilities traditional linters miss.

71 lines 3.14 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ReactSecurityScanner = void 0; const glob_1 = require("glob"); const fs_1 = require("fs"); const rules_1 = require("../rules"); class ReactSecurityScanner { name = 'React Security Scanner'; async scan(options) { const results = []; const files = await (0, glob_1.glob)('**/*.{jsx,tsx}', { cwd: options.directory, ignore: ['node_modules/**', 'dist/**', 'build/**', '.next/**', 'examples/**'] }); // React-specific security rules const reactRuleIds = [ 'TAILWIND001' // Dynamic className Injection ]; for (const file of files) { try { const filePath = `${options.directory}/${file}`; const content = (0, fs_1.readFileSync)(filePath, 'utf-8'); const lines = content.split('\n'); // Apply each React security rule for (const ruleId of reactRuleIds) { const rule = (0, rules_1.getRule)(ruleId); if (!rule || !rule.impl.detect) continue; // Check file type restrictions if (rule.impl.fileTypes) { const fileExt = file.split('.').pop() || ''; if (!rule.impl.fileTypes.includes(fileExt)) continue; } // Run detection const detections = rule.impl.detect(content, file, lines); // Convert detections to ScanResults for (const detection of detections) { const line = lines[detection.line - 1] || ''; results.push({ type: rule.meta.severity === 'high' ? 'error' : 'warning', category: rule.meta.category, message: rule.meta.message, file, line: detection.line, range: { startLine: detection.line, startColumn: 1, endLine: detection.line, endColumn: Math.max(1, line.length) }, severity: rule.meta.severity, ruleId: rule.meta.id, confidence: detection.confidence || 0.80, match: detection.match, fix: rule.meta.fix, helpUri: rule.meta.helpUri, ...(detection.fixEdits ? { fixEdits: detection.fixEdits } : {}) }); } } } catch (error) { // Skip files that can't be read } } return results; } } exports.ReactSecurityScanner = ReactSecurityScanner; //# sourceMappingURL=react-security-scanner.js.map