supabase-audit-rpc
List and test exposed PostgreSQL RPC functions for security issues and potential RLS bypass.
By yoanbernabeu · 439 installs
npx skills add yoanbernabeu/supabase-pentest-skills --skill supabase-audit-rpc
Source repository · Upstream listing
RPC Functions Audit
🔴 CRITICAL: PROGRESSIVE FILE UPDATES REQUIRED
You MUST write to context files AS YOU GO , not just at the end.
Write to .sb pentest context.json IMMEDIATELY after each function tested
Log to .sb pentest audit.log BEFORE and AFTER each function test
DO NOT wait until the skill completes to update files
If the skill crashes or is interrupted, all prior findings must already be saved
This is not optional. Failure to write progressively is a critical error.
This skill discovers and tests PostgreSQL functions exposed via Supabase's RPC endpoint.
When to Use This Skill
To discover exposed database functions
To test if functions bypass RLS
To check for SQL injection in function parameters
As part of comprehensive API security testing
Prerequisites
Supabase URL and anon key available
Tables audit completed (recommended)
Understanding Supabase RPC
Supabase exposes PostgreSQL functions via:
Functions can:
✅ Respect RLS (if using auth.uid() and proper security)
❌ Bypass RLS (if SECURITY DEFINER without checks)
❌ Execute arbitrary SQL (if poorly written)
Risk Levels for Functions
Type Risk Description
SECURITY INVOKER Lower Runs with caller's permissions
SECURITY DEFINER Higher Runs with definer's permissions
Accepts text/json Higher Potential for injection
Returns setof Higher Can return multiple rows
Usage
Basic RPC Audit
Test Specific Function
Output Format
sql
Add authorization check
CREATE OR REPLACE FUNCTION get all users()
RETURNS setof users
LANGUAGE sql
SECURITY INVOKER Change to INVOKER
AS $$
SELECT FROM users
WHERE auth.uid() = id; Add RLS like check
$$;
sql
CREATE OR REPLACE FUNCTION admin delete user(target id uuid)
RETURNS void
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
BEGIN
Add role check
IF NOT (SELECT is admin FROM profiles WHERE id = auth.uid()) THEN
RAISE EXCEPTION 'Unauthorized';
END IF;
DELETE FROM users WHERE id = target id;
END;
$$;
Or better: restrict to authenticated only
REVOKE EXECUTE ON FUNCTION admin delete user FROM anon;
sql
DROP FUNCTION IF EXISTS dynamic query;
Injection Testing
The skill tests for SQL injection in text/varchar parameters:
Safe (Parameterized)
Vulnerable (Concatenation)
Context Output
Best Practices for RPC Functions
1. Prefer SECURITY INVOKER
2. Always Check auth.uid()
3. Use REVOKE for Sensitive Functions
4. Avoid Text Parameters for Dynamic Queries
MANDATORY: Progressive Context File Updates
⚠️ This skill MUST update tracking files PROGRESSIVELY during execution, NOT just at the end.
Critical Rule: Write As You Go
DO NOT batch all writes at the end. Instead:
1. Before testing each function → Log the action to .sb pentest audit.log
2. After each function analyzed → Immediately update .sb pentest context.json
3. After each vulnerability found → Log the finding immediately
This ensures that if the skill is interrupted, crashes, or times out, all findings up to that point are preserved.
Required Actions (Progressive)
1. Update .sb pentest context.json with results:
2. Log to .sb pentest audit.log :
3. If files don't exist , create them before writing.
FAILURE TO UPDATE CONTEXT FILES IS NOT ACCEPTABLE.
MANDATORY: Evidence Collection
📁 Evidence Directory: .sb pentest evidence/03 api audit/rpc tests/
Evidence Files to Create
File Content
function list.json All discovered RPC functions
vulnerable functions/[name].json Details for each vulnerable function
Evidence Format (Vulnerable Function)
Add to curl commands.sh
Related Skills
supabase audit tables list — List exposed tables
supabase audit rls — Test RLS policies
supabase audit auth users — User enumeration tests