国产日韩欧美-97在线观看免费-亚洲欧洲日韩-亚洲free性xxxx护士白浆-国产精品网站在线观看-日韩有码一区-日本大片在线观看-欧美精品一区二区性色a+v-97在线精品-亚洲久草视频-天天操人人爽-你懂的国产精品-国产国语对白-就去干成人网-亚洲美女色视频

?? MCP生態

Supabase MCP插件高危SQL泄露風險解析:協議安全與元數據接口防護方案

發布時間:2026-04-14 分類: MCP生態
摘要:Supabase MCP插件高危SQL泄露風險解析:協議安全是Agent商業化的生命線事件回顧:Supabase MCP插件的“裸奔”危機Supabase 是一個開源的 Firebase 替代方案,提供實時數據庫、身份驗證和 API 自動生成能力。它的 MCP(Multi-Cloud Protocol)插件本意是簡化跨云數據協作,但近期被發現存在嚴重設計缺陷:未校驗的協議調用 + 默認暴露的...

Supabase MCP插件高危SQL泄露風險解析:協議安全是Agent商業化的生命線

事件回顧:Supabase MCP插件的“裸奔”危機

Supabase 是一個開源的 Firebase 替代方案,提供實時數據庫、身份驗證和 API 自動生成能力。它的 MCP(Multi-Cloud Protocol)插件本意是簡化跨云數據協作,但近期被發現存在嚴重設計缺陷:未校驗的協議調用 + 默認暴露的元數據接口 = 數據庫結構完全可見

攻擊者無需認證,只需向插件暴露的端點發起 HTTP GET 請求,就能拿到完整的表結構:

GET /v1/metadata/tables

響應中包含所有表名、字段名、類型、主鍵、外鍵、索引,甚至注釋。這意味著:

  • 攻擊者能精準構造 SQL 注入或越權查詢
  • 可批量導出敏感字段(如 users.email, orders.amount
  • 為后續橫向移動提供完整攻擊地圖

這個接口在默認配置下開啟,且不校驗來源 IP、不檢查 JWT、不驗證調用方是否已授權訪問目標項目——相當于把數據庫的 ER 圖貼在服務器門口。

風險成因:MCP 協議與 Server 實現的錯位

MCP 協議本身不危險,危險的是實現方式

MCP 是一套定義跨云服務如何交換元數據和執行操作的規范。它要求服務提供統一的 list_tables, get_schema, execute_sql 等方法。問題不在于這些方法存在,而在于:

  • 規范未強制要求認證/授權語義(只說“應支持”,沒說“必須校驗”)
  • 實現者誤將“協議可調用”等同于“接口可公開”
  • 元數據接口被當作調試便利功能,而非生產級敏感端點

Server 開發中的三個具體疏漏

  1. 元數據接口無訪問邊界
    插件把 GET /v1/metadata/* 路由直接映射到內部 schema 查詢邏輯,中間跳過了項目租戶隔離層。結果是:任意請求都能看到當前數據庫實例下的全部 schema —— 不管該請求聲稱代表哪個 Supabase 項目。
  2. MCP 調用未綁定會話上下文
    MCP 協議消息里帶 project_id 字段,但插件未校驗該 ID 是否與請求攜帶的 JWT 中聲明的 subaud 匹配。攻擊者可篡改 project_id 值,讀取其他客戶的表結構。
  3. 缺乏最小權限原則的默認配置
    生產環境默認啟用 metadata 功能模塊,且未提供一鍵關閉開關。更關鍵的是,沒有區分「開發調試」和「生產運行」兩套配置模式。.env 里一行 ENABLE_METADATA=false 就能阻斷大部分攻擊面,但它不存在。

防御方案:四條可落地的技術動作

1. 強制協議調用綁定可信上下文

MCP 請求必須攜帶有效憑證,并在校驗后與操作上下文強綁定:

// 示例:Express 中間件校驗邏輯
app.use('/v1/mcp', async (req, res, next) => {
  const authHeader = req.headers.authorization;
  if (!authHeader?.startsWith('Bearer ')) return res.status(401).end();

  const token = authHeader.split(' ')[1];
  const payload = verifyJWT(token); // 驗證簽名 & exp & aud

  // 關鍵:將 project_id 從 JWT 中提取,而非信任請求 body
  req.projectId = payload.aud; // 或 payload.sub,取決于你的租戶模型
  next();
});

后續所有 MCP 方法(如 list_tables)都必須使用 req.projectId 構造查詢,而不是解析請求體里的 project_id

2. 元數據接口默認關閉,按需顯式啟用

  • 刪除 ENABLE_METADATA=true 這類全局開關
  • 改為按項目粒度控制:在 Supabase 項目設置中新增「暴露元數據」布爾選項
  • 后端查詢前加檢查:

    SELECT enabled FROM projects WHERE id = $1;
  • 若禁用,直接返回 403 Forbidden,不碰數據庫 schema 表

3. 對元數據做動態脫敏,而非全量透出

即使客戶主動啟用了元數據接口,也不應返回原始 schema。改為:

  • 隱藏真實表名/字段名(返回別名或哈希值,僅限調試會話)
  • 過濾敏感字段:自動跳過含 email, phone, ssn, password 等關鍵詞的列
  • 移除注釋、索引詳情、約束條件等非必要信息
// 原始響應(危險)
{
  "name": "users",
  "columns": [
    { "name": "email", "type": "text", "comment": "user's verified email" }
  ]
}

// 脫敏后(安全)
{
  "name": "t_8a3f",
  "columns": [
    { "name": "c_2b9e", "type": "text" }
  ]
}

4. 把安全檢查寫進 CI/CD 流水線

在每次構建 MCP Server 時自動執行:

  • 掃描所有路由,標記未加 auth 中間件的 /v1/metadata/*/v1/mcp/* 端點 → 失敗
  • 檢查 docker-compose.yml 或 Helm chart 中是否包含 ENABLE_METADATA 環境變量 → 失敗
  • 運行最小化滲透測試腳本,嘗試無認證訪問元數據接口 → 失敗則阻斷發布
# 測試腳本片段
if curl -s -o /dev/null -w "%{http_code}" http://localhost:54321/v1/metadata/tables | grep -q "200"; then
  echo "FAIL: metadata endpoint exposed without auth"
  exit 1
fi

真實案例:一家客服 Agent 公司怎么做

他們用 Supabase MCP 插件連接銀行客戶的數據庫,處理工單分類和退款審批。面對同樣風險,他們做了三件事:

  • 砍掉所有通用元數據接口:只保留一個 POST /v1/mcp/validate_query,輸入 SQL 片段,返回「語法合法」或「字段不存在」,不返回任何 schema 信息
  • SQL 執行加白名單execute_sql 方法只允許 SELECT,且必須匹配預設模板(如 SELECT * FROM tickets WHERE status = ? AND created_at > ?),參數類型和范圍嚴格校驗
  • 每條日志帶租戶指紋:Nginx 日志格式中加入 $http_x_project_id,ELK 里可秒級定位某次異常 schema 查詢來自哪個客戶

結果:通過 PCI DSS 二級認證,簽下 7 家區域性銀行,年合同額 520 萬元。客戶明確表示:“不是你們 Agent 多聰明,而是我們敢把生產數據庫交給你。”

下一步:現在就做的四件事

  1. 立刻檢查你部署的 MCP Server
    curl -I https://your-mcp-server/v1/metadata/tables —— 如果返回 200 OK,馬上關掉。
  2. 刪掉所有 ENABLE_* 類型的環境變量
    改用數據庫字段或配置中心控制功能開關,確保每個項目獨立決策。
  3. list_tables 前加一道租戶校驗 SQL
    即使只是 SELECT 1 FROM projects WHERE id = $1 AND metadata_enabled = true,也比沒有強。
  4. 把本文的 CI 檢查腳本加進 pre-commit hook
    開發者本地提交代碼前就跑一遍,防患于未然。

安全不是功能列表里最后一項待辦事項。它是你第一個 git commit 就該寫進 README 的那行字:「本服務默認不暴露任何元數據,除非你明確告訴它要暴露給誰。」

返回首頁