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.

43 lines 1.96 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const rule = { meta: { id: 'LOVABLE001', category: 'security', severity: 'high', message: 'Supabase table accessed without RLS policy validation', fix: 'Add RLS policy in Supabase dashboard and document with comment: // RLS enabled for {tableName}', helpUri: 'https://supabase.com/docs/guides/auth/row-level-security', impact: 'Missing RLS can expose all table data to any authenticated user, including PII, financial records, and sensitive information.' }, impl: { detect: (content, file, lines) => { const results = []; const tableAccessPattern = /\.from\(['"`](\w+)['"`]\)\s*\.\s*(select|insert|update|delete|upsert)/gi; let match; while ((match = tableAccessPattern.exec(content)) !== null) { const _tableName = match[1]; // Find line number const beforeMatch = content.substring(0, match.index); const lineNumber = beforeMatch.split('\n').length; // Check if there's RLS documentation nearby (within 5 lines before) const startCheck = Math.max(0, lineNumber - 6); const contextLines = lines.slice(startCheck, lineNumber); const hasRLSComment = contextLines.some(l => /RLS\s+(enabled|policy|configured)/i.test(l) || /Row\s+Level\s+Security/i.test(l) || /auth\.uid\(\)/i.test(l)); if (!hasRLSComment) { results.push({ line: lineNumber, match: match[0], confidence: 0.85 }); } } return results; }, fileTypes: ['js', 'jsx', 'ts', 'tsx'] } }; exports.default = rule; //# sourceMappingURL=LOVABLE001.js.map