news 2026/9/7 1:23:38

Strix supabase 技能深度解析:Supabase 安全测试方法论,从 RLS 绕过到 service_role 密钥泄露

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Strix supabase 技能深度解析:Supabase 安全测试方法论,从 RLS 绕过到 service_role 密钥泄露

Strix supabase 技能深度解析:Supabase 安全测试方法论,从 RLS 绕过到 service_role 密钥泄露

【免费下载链接】strixOpen-source AI penetration testing tool to find and fix your app’s vulnerabilities.项目地址: https://gitcode.com/GitHub_Trending/strix/strix

Strix 内置的supabase技能(supabase.md)是其 Skills 体系中专攻 Supabase 平台的安全测试知识包,覆盖 Row Level Security 失守、PostgREST 越权、RPC 函数滥用、Storage 策略失配、Edge Functions 信任边界与service_role密钥泄露等核心风险面。本文完整继承该技能文档的攻击面模型、端点架构、逐类漏洞测试请求与验证要求,并结合 Strix 源码说明该技能如何被解析、注入 Agent 系统提示词并被执行,帮助读者既掌握一套可复制的 Supabase 渗透测试方法,也理解 AI 渗透工具如何把这类领域知识工程化。

一、技能定位:Supabase 是 Strix technologies 类别下的专项知识包

Strix 的 Skills 是“专业知识包”(knowledge packages):每个技能是一个带 YAML frontmatter 的 Markdown 文件,按需注入 Agent 的上下文,把通用大模型转化为针对特定漏洞类别、协议、框架或第三方平台的专家。官方文档 skills.mdx 在 Technologies 类别中将其描述为:

SkillCoverage
supabaseSupabase RLS bypasses, auth issues

该技能文件的 frontmatter 声明了元数据:

--- name: supabase description: Supabase security testing covering Row Level Security, PostgREST, Edge Functions, and service key exposure ---

从源码结构看,技能文件遵循<root>/<category>/<name>.md的目录约定,内置技能位于 strix/skills/ 下,technologiesvulnerabilitiesprotocolstoolingcloud等并列;skills README 对各类别的分工给出了总览,其中/technologies即“针对 Supabase、Firebase、Auth0 等第三方服务的专项技术”。

二、Supabase 攻击面与端点架构

技能开篇即给出 Supabase 安全测试要聚焦的五个风险点:失域(mis-scoped)RLS 策略、不安全的 RPC 函数、泄露的service_role密钥、宽松的 Storage 策略,以及不校验签发方/受众/租户就信任请求头的 Edge Functions。

2.1 攻击面划分

覆盖内容
数据访问PostgREST(表 CRUD、过滤器、嵌入、RPC 远程函数)、GraphQL(pg_graphql 基于 Postgres schema 并与 RLS 交互)、Realtime(复制订阅、broadcast/presence 频道)
存储Buckets、对象、签名 URL、public/private 策略
认证Auth(GoTrue):JWT、cookie/session、magic links、OAuth 流程
服务端Edge Functions(Deno):持有密钥调用 Supabase 的服务端代码

2.2 端点模型

所有请求都围绕<ref>(项目引用)展开:

服务端点
RESThttps://<ref>.supabase.co/rest/v1/<table>
RPChttps://<ref>.supabase.co/rest/v1/rpc/<fn>
Storagehttps://<ref>.supabase.co/storage/v1
GraphQLhttps://<ref>.supabase.co/graphql/v1
Realtimewss://<ref>.supabase.co/realtime/v1
Authhttps://<ref>.supabase.co/auth/v1
Functionshttps://<ref>.functions.supabase.co/

请求头只有两个关键身份要素:

  • apikey: <anon-or-service>—— 仅用于标识项目(project-scoped),不是用户身份
  • Authorization: Bearer <JWT>—— 绑定用户上下文,用户级鉴权真正发生在这里。

角色模型分三层:

  • anonauthenticated—— 标准角色,受 RLS 约束;
  • service_role——绕过 RLS,绝不应出现在客户端可见的位置(前端 bundle、API 响应、错误栈)。

技能文档反复强调的一条关键原则是:

auth.uid()从 JWT 中返回当前用户 UUID。策略(policy)绝不能信任客户端提供的 ID 而忽视服务端上下文。

这条原则是后文所有 RLS/RPC/租户隔离测试的判据。

2.3 高价值目标清单

测试前优先锁定以下对象:

  • 含敏感数据的表(users、orders、payments、PII);
  • RPC 函数(尤其是SECURITY DEFINER的);
  • 存放私有文件的 Storage buckets;
  • 持有service_role访问权限的 Edge Functions;
  • 生成签名输出的导出/报表端点;
  • 管理员/员工路由与授予权限的端点。

三、侦察:枚举面与获取主体

3.1 枚举表面

按技能文档给出的路径模式逐一探测:

/rest/v1/<table> /rest/v1/rpc/<fn> /storage/v1/object/public/<bucket>/ /storage/v1/object/list/<bucket>?prefix= /graphql/v1 /auth/v1

3.2 获取测试主体(Principals)

  • 未认证身份(仅 anon key);
  • 普通用户 A、用户 B(两个横向对比账号);
  • 管理员/员工身份(若可获取);
  • 检查service_role密钥是否已泄露在客户端 bundle 或 Edge Function 响应中——一旦发现,整个 RLS 防线等于不存在,应第一时间按最高优先级记录。

后续所有测试都围绕“资源 × 操作 × 主体”的矩阵展开。

四、核心漏洞测试方法

4.1 Row Level Security(RLS)

基线要求:每一张非公共表都必须启用 RLS;未启用或存在“全放行”(permit-all)策略即意味着批量数据暴露。

常见缺口

  • 策略只对 SELECT 检查auth.uid(),却忘了 UPDATE/DELETE/INSERT;
  • 缺少租户约束(org_id/tenant_id),导致跨租户访问;
  • 策略依赖客户端传入的列(如 payload 里的user_id)而非 JWT 身份;
  • 复杂 join 场景下策略在过滤器之后才生效,可通过计数差推断数据。

测试请求

# 对比两个用户可见行数 GET /rest/v1/<table>?select=*&Prefer=count=exact # 跨租户探测 GET /rest/v1/<table>?org_id=eq.<other_org> GET /rest/v1/<table>?or=(org_id.eq.other,org_id.is.null) # 写路径 PATCH /rest/v1/<table>?id=eq.<foreign_id> DELETE /rest/v1/<table>?id=eq.<foreign_id> POST /rest/v1/<table> # 携带外部的 owner_id

4.2 PostgREST 与 REST 层

过滤器面eqneqltgtilikeorisin;关系嵌入select=*,profile(*)会在 resolver 跳过逐行检查时造成过度取数(overfetch);宽松的LIKE/ILIKE过滤叠加缺失 RLS 会经通配查询导致批量泄露。

关键请求头

请求头作用
Prefer: return=representation回显写入结果
Prefer: count=exact通过计数暴露数据存在性
Accept-Profile/Content-Profile选择 schema

IDOR 模式

/rest/v1/<table>?select=*&id=eq.<other_id> /rest/v1/<table>?select=*&slug=eq.<other_slug> /rest/v1/<table>?select=*&email=eq.<other_email>

批量赋值(Mass Assignment):若接口未走 RPC 收敛,PATCH 可能更新到不该更新的列;需确认受限列是否通过数据库权限/策略真正锁死,而不只是接口层过滤。

4.3 RPC 函数

RPC 端点映射到 SQL 函数:SECURITY DEFINER以属主权限运行,会绕过 RLS(除非函数体内做了严谨检查);SECURITY INVOKER则以调用者权限运行、尊重 RLS。

反模式

  • SECURITY DEFINER+ 缺少属主校验 → 垂直/水平越权;
  • set search_path暴露给 public,函数解析到不安全对象;
  • 信任客户端传入的user_id/tenant_id而非auth.uid()

测试

# 以不同用户身份、携带外部 ID 调用 POST /rest/v1/rpc/<fn> {"user_id": "<foreign_id>"} # 直接移除 JWT 身份 Authorization: Bearer <anon_token>

验证要点:函数是否在 SQL 内部做了显式的属主/租户检查。

4.4 Storage

对象存放在storage.objects表上,受类 RLS 策略约束。

常见失配

# 公开桶里放了敏感数据 GET /storage/v1/object/public/<bucket>/<path> # 无认证列前缀 GET /storage/v1/object/list/<bucket>?prefix= # 签名 URL 跨租户/跨路径复用

Content-Type 滥用:上传 HTML/SVG 后被以text/htmlimage/svg+xml返回,需检查X-Content-Type-Options: nosniffContent-Disposition: attachment是否生效。

路径混淆:大小写混用、URL 编码、..段可能在 UI 被拒绝却被 API 接受——重点测试客户端校验与服务端路径归一化之间的差异。

4.5 Realtime

端点为wss://<ref>.supabase.co/realtime/v1。风险点:

  • 频道名由表/schema/过滤器派生,RLS 或频道守卫弱时会泄露其他用户的更新;
  • broadcast/presence 频道允许未认证跨房间加入/发布。

测试方法:订阅受保护表的public:realtime变更,确认可见性与 RLS 一致;尝试加入他人频道(room:<user_id>org:<org_id>)。

4.6 GraphQL

端点/graphql/v1(pg_graphql,同样受 RLS 约束)。风险:introspection 泄露 schema 关系;嵌套关系过度取数;全局 node ID 泄露后可被其他视图者复用。

测试方法:对同一主体与同一查询形态,对比 REST 与 GraphQL 的响应;查询深层嵌套字段,验证 RLS 在每一层边上都成立。

4.7 认证与令牌

GoTrue 签发的 JWT 携带sub=uidroleaud=authenticated等声明。验证要求覆盖签发方(issuer)、受众(audience)、过期、签名与租户上下文。

常见陷阱

  • 令牌存 localStorage → 可被 XSS 窃取;
  • apikey当身份用(它只是项目作用域标识);
  • service_role密钥暴露在前端 bundle 或 Edge Function 响应中;
  • Refresh token 管理失当导致会话远超预期 TTL。

测试:把令牌跨服务重放,检查 audience/issuer 是否被固定;用降级令牌(过期/其他受众)打自定义端点。

4.8 Edge Functions

Deno 函数通常以service_role初始化 Supabase 客户端。风险:

  • 不校验 JWT 的签发方/受众就信任 Authorization/apikey 头;
  • CORS 通配 origin 带凭证、响应中反射 Authorization;
  • fetch 触发 SSRF;错误栈或日志暴露密钥。

测试

  • 带/不带 Authorization 分别调用函数,对比行为差异;
  • payload 中塞入外部资源 ID,验证服务端是否从 JWT 重新推导用户/租户;
  • 尝试通过函数内 fetch 触达内部端点(如元数据服务)。

4.9 租户隔离

每条查询都应 join 或过滤 JWT 上下文派生的tenant_id/org_id,而不是客户端输入。测试时保持 JWT 租户不变,只改子域/请求头/路径中的租户选择器;对导出/报表端点确认查询运行在调用者作用域内。

五、进阶技巧:绕过与盲枚举

绕过技术

  • 内容类型切换:application/jsonapplication/x-www-form-urlencodedmultipart/form-data
  • 参数污染:JSON/query 中重复键(PostgREST 依解析器取第一个或最后一个);
  • GraphQL+REST 对等性探测:保护逻辑常在两条路径间漂移,走较弱的一条;
  • 竞态窗口:并行写入以绕过插入后的属主更新。

盲枚举(无响应体差异时的推断)

  • Prefer: count=exact与 ETag/长度差推断未授权行的存在;
  • 条件请求(If-None-Match)检测对象存在性;
  • Storage 签名 URL 的耗时/长度差,用于区分有效与无效令牌。

六、标准测试流程与配套工具

技能文档给出的六步方法论是整套技能的“执行骨架”:

  1. Inventory surfaces—— 测绘 REST、Storage、GraphQL、Realtime、Auth、Functions 端点;
  2. Obtain principals—— 收集 anon、用户 A/B、管理员令牌;检查service_role泄露;
  3. Build matrix—— 建立“资源 × 操作 × 主体”矩阵;
  4. REST vs GraphQL—— 双通道测试以发现对等性缺口;
  5. Seed IDs—— 先从列表/搜索端点收集 ID;
  6. Cross-principal—— 跨主体交换 ID、租户与传输通道。

工具集

领域工具与做法
PostgRESThttpie/curl + jq;枚举表;fuzz 过滤器(or=ilikeneqis.null
GraphQLgraphql-inspector、voyager;深度查询验证字段级强制
Realtime自定义 ws 客户端;订阅可疑频道;按主体 diff payload
Storage枚举桶列 API;脚本化签名 URL 模式
Auth/JWTjwt-cli/jose 校验 audience/issuer;向 Edge Functions 重放
策略 diff按角色维护请求集,跨版本对比结果

验证要求(报告成立门槛)

  • REST/GraphQL 上“属主 vs 非属主”请求,展示未授权访问(内容或元数据层面);
  • 失域 RPC 或 Storage 签名 URL 可被另一用户/租户使用;
  • Realtime 或 GraphQL 暴露与缺失的策略检查一一对应;
  • 附带最小可复现请求,并记录所用角色上下文。

七、Strix 如何加载并执行这个技能

理解了技能内容,再看 Strix 如何把它变成 Agent 的能力。整个链路在源码中清晰可查:

7.1 解析与加载:strix/skills/__init__.py

  • load_skills(skill_names)strix/skills/<category>/<name>.md解析技能,支持裸名supabase或限定名technologies/supabase,解析后剥掉 frontmatter 只注入 Markdown 正文(init.py 中的load_skills_parse_skill_content);
  • validate_requested_skills对每次请求做三重校验:单 Agent 最多 5 个技能、名称必须存在、跨类别重名时必须用category/name限定;
  • get_available_skills()按类别聚合所有技能的 name + description,供系统提示词中的<available_skills>清单渲染。

7.2 注入系统提示词:strix/agents/prompt.py

render_system_prompt调用_resolve_skills构建有序技能列表:调用方显式请求的技能在前,随后固定追加scan_modes/<mode>tooling/agent_browsertooling/pythonanalysis/counterevidenceanalysis/severity_calibration等,根 Agent 还会追加coordination/root_agent(prompt.py)。技能正文经 Jinja 模板渲染进系统提示词,位于 system_prompt.jinja 的<specialized_knowledge>区块中,每个技能独立包在<supabase>等标签内;未预载的技能则列在<available_skills>清单里,由 Agent 运行时按需拉取。

7.3 运行时拉取与子代理分配

两条路径都能让supabase技能生效:

  • 临时内联:Agent 在动手测试前调用 load_skill 工具,技能正文作为工具结果直接进入对话上下文(“no permanent prompt change, just in-conversation reference”);
  • 永久分配:根 Agent 通过create_agent(task=..., skills=[...])生成专职子代理时传入技能列表,子代理系统提示词会完整内联该技能。系统提示词中的多代理规则明确要求“每个 Agent 1-3 个相关技能、最多 5 个”,并给出了类似"Auth Testing Agent" with skills: authentication_jwt, business_logic的专项化范例——对 Supabase 目标,一个典型的委派形态就是“Supabase 数据面 Agent(skills:supabase,idor)”加“Supabase 服务端 Agent(skills:supabase,ssrf)”这样的拆分。

build_strix_agent(factory.py)负责把 skills 参数传给render_system_prompt,并统一挂载thinkload_skillcreate_vulnerability_reportrecord_coverage等基础工具——也就是说,技能文档第六节的“最小可复现请求 + 角色上下文”验证要求,最终由报告工具create_vulnerability_report的字段强制落地,且报告与修复(fix_before/fix_after)在同一步骤内完成。

八、实战入口:在 Strix 中发起一次 Supabase 目标扫描

该技能的适用前提:目标是自托管 Supabase 实例或*.supabase.co项目,且测试已获授权。Strix 的扫描入口按 scan-modes.mdx 提供三档深度,deep 为默认模式:

# 对本地代码 + Supabase 部署目标做深度扫描(白盒 + 动态验证) strix --target ./app --scan-mode deep # CI 场景的快速冒烟 strix --target https://<ref>.supabase.co --scan-mode quick

结合技能文档的方法论,一次典型的 Strix 运行会呈现如下轨迹:根 Agent 只做编排(系统提示词中的 root_agent_directive 明确禁止根 Agent 亲自发 payload),委派子代理按“侦察枚举端点 → 收集 anon/用户 A/B 主体 → 建立资源×操作×主体矩阵 → RLS/RPC/Storage/Realtime/GraphQL 逐面验证 → 用create_vulnerability_report提交带最小可复现请求的报告”的流程执行,每个面(包括干净结果)都会写入record_coverage台账。白盒场景下,仓库中的 supabase client 初始化代码(哪一侧持有service_role)、migration 里的 RLS 策略定义,会成为动态验证的优先线索——这正是技能“策略必须从 JWT 而非客户端输入推导身份”原则的源码级印证方式。

九、小结

supabase技能的价值在于把 Supabase 特有的信任边界(apikey 与 JWT 的分层、auth.uid()作为唯一身份源、service_role的绝对隔离、RLS 覆盖全部 DML 动词)翻译成了一份可直接执行的测试清单:七个端点、九类漏洞面、每类都配了请求级 PoC 与验证门槛。对使用者,它是 Strix 子代理的“领域手册”;对维护者,strix/skills/technologies/supabase.md 本身就是一个符合 Skills 规范 的模板——frontmatter 元数据、攻击面/方法论/绕过/验证的章节骨架,与strix/skills/README.md中对技能结构的定义一一对应。

【免费下载链接】strixOpen-source AI penetration testing tool to find and fix your app’s vulnerabilities.项目地址: https://gitcode.com/GitHub_Trending/strix/strix

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 1:22:00

自动化运维体系设计与实践:从CI/CD到监控日志的DevOps落地指南

简介&#xff1a;面向DevOps的企业自动化运维体系构建PPT&#xff0c;系统拆解了企业自动化运维转型的核心理念、能力框架与落地案例&#xff0c;适合运维工程师、架构师、IT管理者以及DevOps转型团队作为方案规划或内部培训的参考。内容板块包括DevOps是什么、一站式DevOps及运…

作者头像 李华
网站建设 2026/9/7 1:14:35

软件开发求职简历怎么写?一份高通过率的简历模板拆解

简介&#xff1a;这是一份面向计算机软件开发类岗位的求职简历模板&#xff0c;适合正在求职的数据工程师、ETL工程师及相关领域人员参考使用。资源包为1个doc文档&#xff0c;大小仅57KB&#xff0c;内容精炼、结构完整&#xff0c;便于直接下载使用。已有59人学习浏览&#x…

作者头像 李华
网站建设 2026/9/7 1:11:56

MCU芯片赛道深度解读:从选型到实战,避开嵌入式开发那些坑

MCU这个赛道&#xff0c;很少霸榜热搜&#xff0c;但真聊芯片&#xff0c;绕不开它。MCU中文叫微控制器&#xff0c;本质是一颗把CPU、存储和各种外设塞进同一个封装里的芯片。小到电动牙刷里的转速控制&#xff0c;大到汽车车身域控制器里的安全逻辑&#xff0c;背后都是MCU在…

作者头像 李华
网站建设 2026/9/7 1:11:32

数据主权区块链落地实践:个人数据账户系统的设计与实现

简介&#xff1a;一份基于数据主权区块链的个人数据账户系统设计与实现的学士学位毕业论文&#xff0c;面向计算机科学、信息安全等专业的本科与专科毕业生&#xff0c;适用于学术研究、毕业论文选题与写作参考。论文聚焦大数据时代个人数据安全与隐私保护问题&#xff0c;系统…

作者头像 李华
网站建设 2026/9/7 1:09:00

MATLAB函数定义与调用全解析:从脚本到函数的核心规则与避坑指南

简介&#xff1a;MATLAB函数定义与调用是编写结构化程序的重中之重&#xff0c;这份专题文档面向刚接触MATLAB编程的初学者&#xff0c;系统梳理了五种常用的函数定义与调用方式。文档从最基础的函数文件调用命令文件讲起&#xff0c;逐步展开函数文件调用函数文件、函数文件子…

作者头像 李华