性能优化
审计 Supabase RPC 函数时用:发现 RLS…
当需要盘点并测试 Supabase 通过 /rest/v1/rpc/ 暴露的 PostgreSQL 函数及其 RLS 绕过、权限缺失和 SQL 注入风险时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
审计 Supabase RPC 函数时用特定
解决思路
- 先创建或准备跟踪文件:若不存在则创建 `.sb-pentest-context.json` 和 `.sb-pentest-audit.log`,后续执行中逐步写入。
- 对每个函数测试前先写 `.sb-pentest-audit.log`,记录 `[TIMESTAMP] [supabase-audit-rpc] [START] ...`;测试后写 `[FINDING] ...` 和 `[CONTEXT_UPDATED] ...`。
- 每测试或分析完一个函数,立即更新 `.sb-pentest-context.json` 的 `rpc_audit`,不要等全部结束再批量写入;若技能崩溃或中断,已发现结果必须已保存。
- 发现并枚举 Supabase 暴露的 PostgreSQL 函数:通过 `POST https://[project].supabase.co/rest/v1/rpc/[function_name]` 识别可调用的 RPC 函数。
- 为每个函数建立 inventory:记录函数名、参数及类型、Security(`SECURITY INVOKER`/`SECURITY DEFINER`)、Returns、状态(如 `SAFE`/`P0`)和 Analysis。
- 按风险等级判断:`SECURITY INVOKER` 风险较低,按调用者权限运行;`SECURITY DEFINER` 风险较高,按定义者权限运行。
- 继续按风险等级判断:接受 `text/json` 参数的函数风险较高,可能有注入;返回 `setof` 的函数风险较高,可返回多行。
- 可执行两种入口:执行基础 RPC 审计(审计所有 RPC 函数)或测试指定函数(例如测试 `get_user_data` RPC 函数)。
- 对每个函数构造测试请求:使用 `POST /rest/v1/rpc/[function_name]`,带 `apikey: [anon_key]`、`Content-Type: application/json`,按参数传 JSON body。
- 测试函数是否尊重 RLS:若函数使用 `auth.uid()` 且返回调用者自己的数据或受 RLS 过滤的数据,标记为 SAFE;若 `SECURITY DEFINER` 且内部无 `auth.uid()` 检查并返回全量数据,标记为 P0 RLS BYPASS。
- 示例:测试 `get_user_profile(user_id uuid)`,Security INVOKER,Returns json,若有 `auth.uid()` 授权且只返回调用者自己的 profile,则 SAFE。
- 示例:测试 `search_posts(query text)`,Security INVOKER,Returns setof posts,若参数化且 RLS 过滤,只返回已发布 posts,则 SAFE。
- 示例:测试 `get_all_users()`,Security DEFINER,Returns setof users,若无 auth.uid 检查且 `POST /rest/v1/rpc/get_all_users` 返回大量用户 PII,标记为 P0;修复为改为 `SECURITY INVOKER` 并加 `WHERE auth.uid() = id`,或添加授权检查。
- 示例:测试 `admin_delete_user(target_id uuid)`,Security DEFINER,Returns void,若无 role check 且 anon 可调用并删除任意用户,标记为 P0;修复为在函数内检查 `is_admin`,或 `REVOKE EXECUTE ON FUNCTION admin_delete_user FROM anon;`,或限制为 authenticated。
- 示例:测试 `dynamic_query(table_name text, conditions text)`,Security DEFINER,Returns json,若拼接查询,使用 table_name 设为 `users; DROP TABLE users;--`、conditions 设为 `1=1` 的请求验证注入;确认后立即执行 `DROP FUNCTION IF EXISTS dynamic_query;`。
- 示例:测试 `calculate_total(order_id uuid)`,Security INVOKER,Returns numeric,UUID 参数类型安全且 RLS 限制调用者订单,则 SAFE。
- SQL 注入测试:重点测试 `text/varchar` 参数;识别 `EXECUTE format('SELECT json_agg(t) FROM %I t WHERE %s', tbl, cond)` 这类动态 SQL 执行;不要用拼接 SQL 构建查询。
- 安全写法示例:使用参数化查询,例如 `SELECT * FROM posts WHERE title ILIKE '%' || query || '%';` 这类非动态 SQL 执行;漏洞写法是 `EXECUTE format('SELECT json_agg(t) FROM %I t WHERE %s', tbl, cond)`,若参数来自用户则可注入。
- 将发现写入 `.sb-pentest-context.json` 的 `findings`,字段包括 `function`、`severity`、`issue`、`impact`、`remediation`。
- 汇总输出:Total Functions、Safe、P0 Critical、P1 High,并列出每个 P0 函数及优先修复动作(删除、加 auth 检查、改 INVOKER)。
- 证据收集:创建目录 `.sb-pentest-evidence/03-api-audit/rpc-tests/`。
- 在证据目录写 `function-list.json`,记录所有发现的 RPC 函数。
- 对每个漏洞函数写 `vulnerable-functions/[name].json`,格式包含 `evidence_id`、`timestamp`、`category`、`type`、`severity`、`function`、`analysis`(如 `security_definer`/`auth_check`/`rls_bypass`)、`test.request`(`method`/`url`/`curl_command`)、`test.response`(`status`/`rows_returned`/`sample_data` 脱敏)、`impact`、`remediation`。
- 将 RPC 测试命令加入 `curl-commands.sh`:`curl -X POST "$SUPABASE_URL/rest/v1/rpc/get_all_users" -H "apikey: $ANON_KEY" -H "Content-Type: application/json"`;以及 `curl -X POST "$SUPABASE_URL/rest/v1/rpc/admin_delete_user" -H "apikey: $ANON_KEY" -H "Content-Type: application/json" -d '{"target_id": "test-uuid"}'`。
- 最佳实践:函数优先使用 `SECURITY INVOKER` 以尊重 RLS。
- 最佳实践:始终在函数内检查 `auth.uid()`,例如 `WHERE d.user_id = auth.uid();`。
- 最佳实践:对敏感函数使用 `REVOKE EXECUTE ON FUNCTION admin_function FROM anon;`,仅 `GRANT EXECUTE ... TO authenticated;`。
- 最佳实践:避免用 `text` 参数做动态查询,按表拆成具体函数,如 `get_users()`、`get_posts()`。
- 相关技能可联动:`supabase-audit-tables-list` 列出暴露表,`supabase-audit-rls` 测试 RLS,`supabase-audit-auth-users` 做用户枚举。
适用边界 · 注意事项
- 未获得目标 Supabase 项目授权时不要执行 RPC 安全测试。
- 非 Supabase 或非 PostgreSQL RPC 暴露面不适用。
- 没有 Supabase URL 或 anon key 时无法按本流程审计。