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.

57 lines 2.59 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const rule = { meta: { id: 'LOVABLE005', category: 'security', severity: 'medium', message: 'Weak RLS policy pattern detected', fix: 'Use auth.uid() checks to restrict access to user\'s own data: USING (auth.uid() = user_id)', helpUri: 'https://supabase.com/docs/guides/auth/row-level-security#policies', impact: 'Weak RLS policies may allow users to access other users\' data, violating privacy and security.' }, impl: { detect: (content, _file, _lines) => { const results = []; // Look for SQL policy definitions in comments or separate .sql files const weakPolicyPatterns = [ // USING (true) - always allows access { pattern: /USING\s*\(\s*true\s*\)/gi, confidence: 0.90 }, // Overly broad authenticated role without auth.uid() { pattern: /auth\.role\(\)\s*=\s*['"`]authenticated['"`](?!.*auth\.uid\(\))/gi, confidence: 0.75 } ]; // Check for CREATE POLICY without auth.uid() const policyPattern = /CREATE\s+POLICY[^;]+USING\s*\([^)]+\)/gis; let policyMatch; while ((policyMatch = policyPattern.exec(content)) !== null) { const policyText = policyMatch[0]; // Check if policy doesn't contain auth.uid() if (!/auth\.uid\(\)/i.test(policyText)) { const beforeMatch = content.substring(0, policyMatch.index); const lineNumber = beforeMatch.split('\n').length; results.push({ line: lineNumber, match: policyText.slice(0, 100), confidence: 0.80 }); } } for (const { pattern, confidence } of weakPolicyPatterns) { let match; while ((match = pattern.exec(content)) !== null) { const beforeMatch = content.substring(0, match.index); const lineNumber = beforeMatch.split('\n').length; results.push({ line: lineNumber, match: match[0].slice(0, 100), confidence }); } } return results; }, fileTypes: ['js', 'jsx', 'ts', 'tsx', 'sql'] } }; exports.default = rule; //# sourceMappingURL=LOVABLE005.js.map