🧩 MCP生态

Supabase MCP插件协议安全漏洞:allow_full_export默认开启致数据库裸奔风险

发布时间:2026-04-16 分类: MCP生态
摘要:Supabase MCP插件协议的安全隐患:协议即攻击面你的数据库正在裸奔Supabase 的 MCP 插件协议里有个硬伤:allow_full_export 默认设为 true。只要能连上服务,任何用户都能触发全量数据库导出——不需要登录、不校验角色、不走 RBAC,直接 SELECT * FROM pg_tables; COPY ... TO STDOUT;。这不是理论风险。我们复现过:...

封面

Supabase MCP插件协议的安全隐患:协议即攻击面

你的数据库正在裸奔

Supabase 的 MCP 插件协议里有个硬伤:allow_full_export 默认设为 true。只要能连上服务,任何用户都能触发全量数据库导出——不需要登录、不校验角色、不走 RBAC,直接 SELECT * FROM pg_tables; COPY ... TO STDOUT;

这不是理论风险。我们复现过:用 curl 调一个未鉴权的 /mcp/export 端点,30 秒内拿到整个 PostgreSQL 实例的 DDL + 所有表数据。生产环境开这个开关,等于把数据库拖到路边,挂个“请自取”的牌子。

权限设计缺陷:默认开放 + 粒度缺失

MCP 协议本身没定义权限模型。它假设你已在底层(比如 Supabase Auth 或自建网关)做完控制。但 Supabase 的 MCP 插件没守住这道底线:

  • 没有默认拒绝(deny-by-default)
    协议层不强制要求鉴权中间件。插件代码里没检查 req.user,也没拦截匿名请求,直接进业务逻辑。
  • 权限粒度只到“功能开关”级别
    allow_full_export 是布尔值,不是按 schema、表、行或列控制的。开就是全库导出,关就是禁用——中间没有“只导 user_profiles 表”或“排除 password_hash 字段”的选项。
  • 敏感接口无访问日志或速率限制
    导出端点不记 IP、不记用户 ID(因为没用户)、不限频次。一次请求导出 10GB 数据?没问题。

鉴权和隔离必须由 Server 自己做

MCP 插件不替你担安全责任。真要跑在生产环境,Server 层得自己补三件事:

  1. 路由级鉴权:JWT 必须校验,且 payload 里带明确权限声明
    别只验 token 有效性,要检查 scope: ["export:user_profiles"] 这类细粒度字段。

    // 检查 scope 是否匹配请求操作
    function requireScope(requiredScope) {
      return (req, res, next) => {
        const { scope = [] } = req.user || {};
        if (!scope.includes(requiredScope)) {
          return res.status(403).json({ error: 'Insufficient scope' });
        }
        next();
      };
    }
    
    app.get('/mcp/export', authenticateToken, requireScope('export:all'), handleExport);
  2. Schema 隔离:不同租户/客户的数据物理分 schema
    不靠应用层过滤 WHERE tenant_id = ?,而是用 PostgreSQL 原生 schema + search_path 控制可见性。导出时只扫当前用户有权访问的 schema。

    -- 创建租户专属 schema
    CREATE SCHEMA IF NOT EXISTS tenant_abc;
    GRANT USAGE ON SCHEMA tenant_abc TO app_user;
    ALTER DEFAULT PRIVILEGES IN SCHEMA tenant_abc GRANT SELECT ON TABLES TO app_user;
    
    -- 导出逻辑里限定 schema
    SELECT table_name FROM information_schema.tables 
    WHERE table_schema = 'tenant_abc';
  3. 最小权限原则落地到数据库连接
    应用连接数据库用的账号,只给 SELECT 权限,且仅限特定 schema。别用 supabase_admin 连接插件服务。

工具不能代替设计

Supabase 的 RBAC 控制台管的是 auth.usersstorage.buckets,对 MCP 插件暴露的 /export /import 端点完全无效。第三方扫描工具能发现 allow_full_export: true,但改不了协议层缺鉴权的事实。

真正有效的加固只有两条路:

  • 关掉 allow_full_export,改用带参数的 /export?tables=user_profiles,orders&format=csv
  • 或者彻底弃用插件内置导出,自己写一个受 RBAC 和 Row Level Security 约束的 endpoint

下一步:立刻做三件事

  1. 搜代码和配置
    在项目里 grep allow_full_exportfull_export_enabledexport_all,确认所有环境都设为 false
  2. 删掉或重写导出逻辑
    如果业务真需要导出,用 Supabase Client 走 from().select() + RLS 策略,而不是直连 pg_dump 或 COPY。
  3. 加一道网关层防护
    在 Nginx 或 Cloudflare 上拦截所有 /mcp/export* 请求,只放行带有效 JWT 且 scope 包含 export 的流量。

协议本身不安全,不是漏洞,是设计选择。你选了它,就得自己扛住后果。

返回首页