Skip to content

About

Security scanner for Supabase and Lovable projects. Audits Row Level Security (RLS) policies.

Resources

Stars

23 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Vibe-Scanner

Security scanner for Supabase and Lovable projects. Audits Row Level Security (RLS) policies by analyzing SQL migrations locally or querying live databases remotely. Detects misconfigurations, missing protections, and common security anti-patterns.

What it does

Vibe-Scanner reads your Supabase migration files (or connects directly to your live database), builds the final state of every table's RLS configuration, and runs 62 detection rules against it. It catches issues like:

  • Tables with RLS enabled but no policies defined
  • Policies using USING(true) or other tautologies (NOT FALSE, 1=1)
  • UPDATE policies missing WITH CHECK clauses
  • Missing FORCE ROW LEVEL SECURITY
  • SECURITY DEFINER functions without search_path reset
  • Views missing SECURITY INVOKER
  • GRANT TO PUBLIC on tables with RLS
  • Roles with BYPASSRLS privilege
  • Realtime publications on tables without restrictive RLS
  • Hardcoded secrets in config.toml

What it does not do

Vibe-Scanner is a read-only auditing tool. It detects and reports, but it does not modify your database, apply fixes, or patch your code. If you find yourself vulnerable, we're temporarily giving free access to Symbiotic Code so you can remediate. Not a sales trick, just trying to be helpful without having to carve out a new tool from our product.

Installation

uv sync

Usage

Local scan (SQL migration files)

# Console output (Rich-formatted, grouped by table)
uv run rls-scanner ./path/to/supabase/

# JSON report
uv run rls-scanner ./path/to/supabase/ -o json -f report.json

# Markdown report
uv run rls-scanner ./path/to/supabase/ -o markdown -f report.md

# Custom rules file
uv run rls-scanner ./path/to/supabase/ -r custom_rules.yaml

# Visual graph outputs
uv run rls-scanner ./path/to/supabase/ -o mermaid-er        # ER diagram
uv run rls-scanner ./path/to/supabase/ -o mermaid-security  # Security flow
uv run rls-scanner ./path/to/supabase/ -o graph-json        # Machine-readable graph

Remote scan — Supabase Management API

Scan a live Supabase database directly using a personal access token. This finds more vulnerabilities than local scanning because it sees the actual deployed state (storage tables, system roles, SECURITY DEFINER functions).

# Basic remote scan
uv run rls-scanner -t sbp_xxxxx -p <project_ref>

# JSON output
uv run rls-scanner -t sbp_xxxxx -p <project_ref> -o json -f report.json

# Scan a specific schema
uv run rls-scanner -t sbp_xxxxx -p <project_ref> --schema public

# Using environment variables
export SUPABASE_ACCESS_TOKEN=sbp_xxxxx
export SUPABASE_PROJECT_REF=yitwhbimoqlwfridlxak
uv run rls-scanner

Remote scan — Lovable (DB proxy)

Scan Supabase databases managed by Lovable via their internal DB proxy. The Supabase ref is auto-discovered from the Lovable API.

# Scan a single project (supabase ref auto-discovered)
uv run rls-scanner \
  --lovable-token "eyJxxx..." \
  --lovable-project "40d72bc5-5e42-4b7d-aba4-15e37e5433fc"

# Also accepts the full Lovable URL
uv run rls-scanner \
  --lovable-token "eyJxxx..." \
  --lovable-project "https://lovable.dev/projects/40d72bc5-5e42-4b7d-aba4-15e37e5433fc"

# Scan ALL projects in your workspace at once
uv run rls-scanner --lovable-token "eyJxxx..." --lovable-scan-all

# JSON output
uv run rls-scanner \
  --lovable-token "eyJxxx..." \
  --lovable-project "40d72bc5-..." \
  -o json -f report.json

# Using environment variables
export LOVABLE_TOKEN="eyJxxx..."
export LOVABLE_PROJECT_ID="40d72bc5-5e42-4b7d-aba4-15e37e5433fc"
uv run rls-scanner

# Scan all projects with env variable
export LOVABLE_TOKEN="eyJxxx..."
uv run rls-scanner --lovable-scan-all

# Override supabase ref manually (skips auto-discovery)
uv run rls-scanner \
  --lovable-token "eyJxxx..." \
  --lovable-project "40d72bc5-..." \
  --supabase-ref "rscgeiiibodxpqpwojfz"

How to get the Lovable token:

  1. Open https://lovable.dev in Chrome
  2. Open DevTools (F12) > Network tab
  3. Filter requests to api.lovable.dev
  4. Copy the Authorization: Bearer eyJ... header from any request Then run:
uv run rls-scanner --lovable-token "eyJxxx..." --lovable-scan-all
uv run rls-scanner --lovable-token "eyJxxx..." --lovable-project "40d72bc5-..."

Local vs Remote — what's different?

Local scan Remote scan (Supabase / Lovable)
Source SQL migration files Live database (pg_class, pg_policies, pg_proc, etc.)
Storage tables Not visible storage.objects, storage.buckets scanned
System roles Not visible BYPASSRLS roles detected (e.g. service_role)
SECURITY DEFINER Only if in migrations All functions from pg_proc
Realtime check Only if ALTER PUBLICATION in SQL Queries pg_publication_tables directly

The scanner exits with code 1 if any CRITICAL or HIGH findings are detected, making it usable in CI pipelines.

How the scanner works

Pipeline overview

SQL files (sorted by name = migration order)
  |
  v
+---------------------------------------------+
|  SQL Parser (regex + pglast AST)            |
|  Extracts: tables, policies, grants, roles, |
|  functions, views, realtime subscriptions   |
+-----------------------+---------------------+
                        |  Mutations applied in order
                        v
+---------------------------------------------+
|  Migration State                            |
|  Temporal tracking: CREATE, ALTER, DROP      |
|  Final state per table: RLS on/off,         |
|  policies, FORCE RLS, columns               |
+-----------------------+---------------------+
                        |  One RLSTableConfig per table
                        v
+---------------------------------------------+
|  Vulnerability Detectors (per table)        |
|  + Cross-cutting checks (grants, roles,     |
|    realtime, config.toml)                   |
+-----------------------+---------------------+
                        |  Findings deduplicated
                        v
+---------------------------------------------+
|  Reporter (console / JSON / markdown)       |
+---------------------------------------------+

Parsing layer

The scanner uses two complementary parsers:

Parser Technology Role
SQLParserAdapter Regex patterns Main parser. Extracts tables, policies, grants, roles, functions, views, triggers, and realtime publications from SQL. Fast and handles Supabase-specific syntax.
PostgreSQLASTParser pglast v7 (libpg_query) Parses policy expressions (USING, WITH CHECK) into a real PostgreSQL AST. Detects auth function calls, tautologies, subqueries, operators, column/table references with high accuracy. Falls back to regex if pglast is unavailable or the expression cannot be parsed.

The parsing is temporal: migration files are processed in sorted order. CREATE POLICY, DROP POLICY, ENABLE RLS, DISABLE RLS are tracked as mutations. The scanner analyzes the final state after all migrations have been applied.

Detection layer

Detection is split across specialized detectors, each responsible for a category of vulnerabilities:

Detector Rules What it checks
VulnerabilityDetector RLS-001 to RLS-007 RLS enabled, policies exist, missing CRUD operations
PolicyStructureChecker RLS-010 to RLS-015, RLS-024, RLS-026, RLS-049 Clause issues (INSERT without WITH CHECK, UPDATE without WITH CHECK), role issues (service_role), OR without auth, FOR ALL policies
UsingClauseChecker RLS-008, RLS-016 to RLS-023, RLS-025, RLS-027 to RLS-030, RLS-047, RLS-048 Auth checks in USING clause, tautologies, subquery patterns, operator issues, non-existent columns, infinite loops
WithCheckChecker RLS-008, RLS-018, RLS-025, RLS-057 Auth checks in WITH CHECK clause, tautologies, custom functions
ColumnAccessDetector RLS-031 to RLS-033, RLS-050 Sensitive column exposure, missing column-level restrictions
SecurityDefinerDetector RLS-034 to RLS-040 SECURITY DEFINER functions: missing search_path, missing auth, dynamic SQL, data exposure
ViewSecurityDetector RLS-041, RLS-044, RLS-045 Views missing SECURITY INVOKER, views using SECURITY DEFINER
Cross-cutting checks RLS-051 to RLS-062 DEFINER/view usage in policies, FORCE RLS, GRANT TO PUBLIC, BYPASSRLS roles, realtime tables, config.toml issues

All 62 rules are defined in config/rules.yaml and can be customized.

Rule ID registry

Every rule ID is declared in src/domain/rules/rule_ids.py as a Rule(str, Enum), grouped by category.

Severity levels

Level Meaning
CRITICAL Immediate fix required — data is exposed (e.g. USING(true))
HIGH Significant security gap (e.g. missing FORCE RLS, no auth check)
MEDIUM Moderate risk (e.g. subquery joining source table, missing operation)
LOW Minor gap (e.g. missing DELETE policy)
WARNING Best practice recommendation (e.g. custom function without verification)

Project structure

src/
├── main.py                              # CLI entry point (Click)
├── main_helpers.py                      # Shared scan result helpers
├── main_lovable.py                      # Lovable scan entry points
├── domain/                              # Domain layer (no external dependencies)
│   ├── models/                          # Pydantic models, dataclasses, enums
│   ├── ports/                           # Abstract interfaces (parser, detector, remote DB)
│   └── rules/                           # Rule loader, rule IDs enum, finding factory
├── application/                         # Application layer (orchestration)
│   ├── services/                        # ScannerService, remote scanner, cross-cutting checks
│   └── use_cases/                       # ScanUseCase entry point
└── infrastructure/                      # Infrastructure layer (adapters)
    ├── parsers/                         # SQL regex parser, pglast v7 AST, regex fallback
    ├── detectors/                       # All vulnerability detectors
    ├── reporters/                       # Console (Rich), JSON, Markdown, Mermaid, Graph
    └── remote/                          # Supabase API adapter, Lovable API client
config/
└── rules.yaml                           # 62 vulnerability rules (YAML)

About

Security scanner for Supabase and Lovable projects. Audits Row Level Security (RLS) policies.

Resources

Stars

23 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages