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

?? MCP生態(tài)

Supabase MCP安全漏洞詳解:allow_unrestricted_queries配置錯(cuò)誤致PostgreSQL全庫(kù)泄露

發(fā)布時(shí)間:2026-04-13 分類: MCP生態(tài)
摘要:Supabase MCP安全漏洞實(shí)戰(zhàn)警示:SQL數(shù)據(jù)庫(kù)全量泄露是怎么發(fā)生的?MCP配置錯(cuò)誤導(dǎo)致全庫(kù)泄露的真實(shí)案例Hacker News上有個(gè)開(kāi)發(fā)者貼出自己的事故復(fù)盤:他用Supabase MCP連接PostgreSQL,只改了一行配置,結(jié)果整個(gè)數(shù)據(jù)庫(kù)被爬空。問(wèn)題出在supabase.toml里這行:[database] # 錯(cuò)誤配置:允許任意客戶端執(zhí)行任意查詢 allow_unrestric...

Supabase MCP安全漏洞實(shí)戰(zhàn)警示:SQL數(shù)據(jù)庫(kù)全量泄露是怎么發(fā)生的?

MCP配置錯(cuò)誤導(dǎo)致全庫(kù)泄露的真實(shí)案例

Hacker News上有個(gè)開(kāi)發(fā)者貼出自己的事故復(fù)盤:他用Supabase MCP連接PostgreSQL,只改了一行配置,結(jié)果整個(gè)數(shù)據(jù)庫(kù)被爬空。

問(wèn)題出在supabase.toml里這行:

[database]
# 錯(cuò)誤配置:允許任意客戶端執(zhí)行任意查詢
allow_unrestricted_queries = true

MCP Server啟動(dòng)后,攻擊者直接連上mcp://<host>:6543,發(fā)了個(gè)SELECT * FROM users;,接著是SELECT * FROM payments;,最后把整庫(kù)pg_dump走。沒(méi)有認(rèn)證繞過(guò),沒(méi)有0day,純屬配置放開(kāi)+暴露端口。

MCP協(xié)議本身不危險(xiǎn),危險(xiǎn)的是默認(rèn)行為和權(quán)限模型

MCP不是新協(xié)議,它是Supabase為簡(jiǎn)化多云數(shù)據(jù)同步封裝的一層gRPC/HTTP網(wǎng)關(guān)。它的風(fēng)險(xiǎn)點(diǎn)很具體:

  • 端口暴露即入口:MCP Server默認(rèn)監(jiān)聽(tīng)6543(非PostgreSQL原生端口),但只要防火墻放行、沒(méi)配TLS或IP白名單,就等于把數(shù)據(jù)庫(kù)門把手焊死在大街上
  • 權(quán)限繼承混亂:MCP不自動(dòng)繼承PostgreSQL的行級(jí)策略(RLS)。你數(shù)據(jù)庫(kù)里開(kāi)了ENABLE ROW LEVEL SECURITY,MCP照樣能繞過(guò)——除非顯式啟用enable_rls = true并綁定策略函數(shù)
  • 角色映射缺失:Supabase Auth的auth.uid()在MCP上下文中默認(rèn)不可用。不手動(dòng)注入x-user-id頭或配置JWT解析,所有請(qǐng)求都以postgres超級(jí)用戶身份執(zhí)行

三個(gè)必須落地的防護(hù)動(dòng)作

1. 權(quán)限隔離:砍掉所有“全局”權(quán)限

Supabase MCP不支持GRANT ALL ON DATABASE這種粗粒度授權(quán)。必須按表、按列、按操作精確控制:

// 正確做法:創(chuàng)建專用MCP角色,僅授予必要權(quán)限
await supabase.rpc('create_mcp_role', {
  role_name: 'mcp_reader',
  schema: 'public',
  table: 'orders',
  columns: ['id', 'status', 'created_at'],
  permissions: ['SELECT']
});

對(duì)應(yīng)SQL:

-- 在PostgreSQL中執(zhí)行
CREATE ROLE mcp_reader;
GRANT USAGE ON SCHEMA public TO mcp_reader;
GRANT SELECT(id, status, created_at) ON TABLE public.orders TO mcp_reader;
-- 禁止該角色訪問(wèn)敏感表
REVOKE ALL ON TABLE public.payments FROM mcp_reader;

2. 策略校驗(yàn):用RLS兜底,別信應(yīng)用層過(guò)濾

MCP支持透?jìng)鱎LS策略,但需要顯式開(kāi)啟。在supabase.toml中:

[database]
# 必須設(shè)為true,否則RLS完全失效
enable_rls = true

[database.rls_policies]
# 綁定策略函數(shù)到具體表
"public.orders" = "user_can_read_order"

對(duì)應(yīng)的策略函數(shù):

CREATE POLICY user_can_read_order ON public.orders
  FOR SELECT
  USING (auth.uid() = user_id OR is_admin());

3. RBAC集成:把Auth角色映射到MCP會(huì)話

MCP Server啟動(dòng)時(shí)需加載Supabase JWT密鑰,并在請(qǐng)求頭中傳遞Authorization: Bearer <token>

# 啟動(dòng)命令必須包含JWT驗(yàn)證配置
supabase start --mcp-jwt-secret=your-supabase-jwt-secret

服務(wù)端自動(dòng)解析role字段,映射到PostgreSQL角色。不需要手寫(xiě)setAuth()——那是前端SDK的邏輯,MCP Server要的是后端可信身份。

復(fù)盤那個(gè)被拖庫(kù)的配置

回到開(kāi)頭的事故,真正的問(wèn)題鏈?zhǔn)牵?/p>

  1. supabase.tomlallow_unrestricted_queries = true(默認(rèn)為false
  2. 防火墻開(kāi)放了6543端口給0.0.0.0/0
  3. 沒(méi)啟用enable_rls = true,PostgreSQL的RLS策略形同虛設(shè)
  4. 數(shù)據(jù)庫(kù)連接池用的是postgres超級(jí)用戶,而非最小權(quán)限角色

修復(fù)只需三步:

  • allow_unrestricted_queries = false
  • enable_rls = true并綁定策略
  • DATABASE_URL里的postgres換成專用角色mcp_reader

別依賴課程,先做這三件事

安全不是學(xué)出來(lái)的,是改出來(lái)的:

  1. 立刻檢查你的supabase.toml:搜allow_unrestricted_queriesenable_rls,確認(rèn)值符合生產(chǎn)要求
  2. 登錄數(shù)據(jù)庫(kù)執(zhí)行\du:看是否存在mcp_*專用角色,且沒(méi)被賦予SUPERUSERCREATEDB權(quán)限
  3. nc -zv your-host 6543測(cè)試端口:如果公網(wǎng)可連,加防火墻規(guī)則或改用VPC內(nèi)網(wǎng)通信

MCP本身沒(méi)問(wèn)題。出問(wèn)題的是把數(shù)據(jù)庫(kù)當(dāng)玩具配的習(xí)慣。

返回首頁(yè)