Supabase MCP插件安全漏洞分析:SQL權(quán)限校驗(yàn)缺失與Server加固實(shí)踐

Supabase MCP插件安全漏洞分析:協(xié)議缺陷與Server加固實(shí)踐
漏洞本質(zhì):權(quán)限校驗(yàn)完全缺失
Supabase MCP插件暴露了一個(gè)關(guān)鍵問題:它把MCP請(qǐng)求當(dāng)作可信輸入直接執(zhí)行,跳過了所有權(quán)限檢查。任何能連上MCP Server的Agent,都能調(diào)用sql_query工具并傳入任意SQL——包括SELECT * FROM auth.users或DROP TABLE public.products。這不是配置疏忽,而是協(xié)議實(shí)現(xiàn)層面的空白。
這個(gè)漏洞和Supabase本身無關(guān)。Supabase的Row Level Security(RLS)依然生效,但MCP插件繞過了整個(gè)RLS鏈路,直連PostgreSQL后端。結(jié)果就是:Agent權(quán)限模型在MCP層徹底失效。
MCP協(xié)議中本該存在的三道防線
MCP協(xié)議本身不強(qiáng)制權(quán)限控制,但它定義了三個(gè)可落地的控制點(diǎn)。插件沒用它們,才導(dǎo)致全線失守。
1. Capability聲明必須綁定到具體操作
Capability不是裝飾性字段。它應(yīng)該明確列出Agent被允許調(diào)用的工具名和參數(shù)約束。例如:
{
"capabilities": [
{
"name": "sql_query",
"parameters": {
"table": ["users", "profiles"],
"allowed_operations": ["SELECT"]
}
}
]
}如果Agent聲明里沒包含sql_query,Server就該拒絕該請(qǐng)求,而不是放行后才查權(quán)限。
2. Scope必須限制數(shù)據(jù)邊界
Scope不是模糊的“數(shù)據(jù)庫訪問”,而是精確到表、字段、甚至WHERE條件。比如一個(gè)客服Agent的Scope應(yīng)類似:
"scope": {
"tables": ["public.users"],
"fields": ["id", "email", "created_at"],
"where_clause": "status = 'active'"
}MCP Server收到sql_query時(shí),必須解析SQL,提取目標(biāo)表和字段,再比對(duì)Scope。SELECT * FROM users這種全量查詢,在Scope含fields: ["email"]時(shí)就應(yīng)該被攔截。
3. Resource-level ACL需在Server端強(qiáng)制執(zhí)行
ACL不能只存在文檔里。MCP Server啟動(dòng)時(shí),必須加載一份資源策略表,并在每次請(qǐng)求前查表:
| Resource | Agent ID | Allowed Actions | Conditions |
|---|---|---|---|
public.users | agent-1 | SELECT | WHERE role = 'admin' |
public.posts | agent-2 | INSERT | CHECK (length(content) < 500) |
沒有這張表,就沒有真正的Resource-level ACL。
漏洞復(fù)現(xiàn)與影響范圍
攻擊者只需構(gòu)造一個(gè)合法MCP請(qǐng)求包:
{
"type": "tool_call",
"tool": "sql_query",
"arguments": {
"query": "COPY (SELECT * FROM auth.users) TO '/tmp/dump.csv' WITH CSV"
}
}只要MCP Server監(jiān)聽公網(wǎng)且未設(shè)網(wǎng)絡(luò)層防護(hù),這條請(qǐng)求就能導(dǎo)出全部用戶憑證。我們實(shí)測(cè)發(fā)現(xiàn),該插件默認(rèn)啟用pg_read_server_files擴(kuò)展,使得文件寫入成為可能——這已超出數(shù)據(jù)泄露,進(jìn)入系統(tǒng)接管風(fēng)險(xiǎn)。
更隱蔽的問題是:漏洞影響所有基于該插件構(gòu)建的Agent。即使你給Agent配了嚴(yán)格Capability,只要插件代碼沒讀取這些字段,一切聲明都形同虛設(shè)。
Server加固:四步落地
1. 在入口處硬性校驗(yàn)Capability
不要等請(qǐng)求進(jìn)到業(yè)務(wù)邏輯才檢查。MCP Server的路由層就要做兩件事:
- 解析Agent的Capability聲明(從JWT claim、注冊(cè)元數(shù)據(jù)或會(huì)話上下文獲?。?/li>
- 對(duì)比當(dāng)前請(qǐng)求的
tool名是否在聲明列表中
function validateToolCall(agentCaps, toolName) {
const cap = agentCaps.find(c => c.name === toolName);
if (!cap) throw new PermissionError(`Tool '${toolName}' not allowed`);
// 還可校驗(yàn)參數(shù)結(jié)構(gòu),如禁止傳入DROP語句
return cap;
}
// 在Express中間件中調(diào)用
app.post('/mcp', (req, res) => {
const { tool, arguments } = req.body;
const caps = getAgentCapabilities(req.headers.authorization);
validateToolCall(caps, tool); // 攔截點(diǎn)在此
handleTool(tool, arguments);
});2. SQL解析器必須嵌入Scope檢查
別依賴開發(fā)者手寫安全SQL。所有sql_query調(diào)用前,必須過一遍輕量SQL解析器(如sql-parser-js),提取AST中的table, columns, where節(jié)點(diǎn),再與Scope比對(duì)。
重點(diǎn)攔截:
SELECT *(除非Scope顯式聲明fields: ["*"])- 跨Schema查詢(如
SELECT * FROM auth.users) INSERT/UPDATE/DELETE無WHERE條件COPY,CREATE FUNCTION,DO $$等高危語法
3. 協(xié)議層加簽與限流
MCP本身不加密,但Server可以要求:
- 所有請(qǐng)求帶HMAC簽名(密鑰由Agent注冊(cè)時(shí)分配)
- 每個(gè)Agent每分鐘最多10次
sql_query調(diào)用 - 連續(xù)3次失敗請(qǐng)求后,臨時(shí)封禁該Agent ID 5分鐘
簽名驗(yàn)證示例:
const crypto = require('crypto');
function verifySignature(req, secret) {
const signature = req.headers['x-mcp-signature'];
const body = JSON.stringify(req.body);
const expected = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return signature === expected;
}4. 審計(jì)日志必須包含可追溯字段
每條MCP請(qǐng)求日志至少記錄:
- Agent ID(非用戶名)
- 請(qǐng)求時(shí)間戳(ISO 8601)
- 工具名 + 參數(shù)摘要(如
sql_query: SELECT id,email FROM users LIMIT 10) - 執(zhí)行耗時(shí) + 返回行數(shù)
- 是否觸發(fā)權(quán)限拒絕(標(biāo)記為
DENIED)
日志不存本地磁盤,直接發(fā)到Loki或Datadog。拒絕事件必須觸發(fā)PagerDuty告警。
合規(guī)Agent的務(wù)實(shí)變現(xiàn)路徑
安全加固不是PPT方案,而是可交付的工程能力。合規(guī)Agent能做的不是賣“安全咨詢”,而是提供以下可集成模塊:
1. MCP ACL SDK
一個(gè)NPM包,封裝上述四步加固邏輯:
npm install @compliant/mcp-acl開箱即用的Express中間件 + Supabase客戶端適配器 + 預(yù)置SQL解析規(guī)則。企業(yè)只需改兩行代碼:
const { aclMiddleware } = require('@compliant/mcp-acl');
app.use(aclMiddleware({ supabaseUrl, supabaseAnonKey }));2. Scope策略生成器
CLI工具,根據(jù)Supabase RLS策略自動(dòng)生成MCP Scope:
npx @compliant/mcp-scope-gen \
--supabase-url https://xxx.supabase.co \
--anon-key ey... \
--agent-id support-agent輸出JSON格式Scope,直接注入Agent注冊(cè)流程。
3. 實(shí)時(shí)審計(jì)儀表盤
部署一個(gè)輕量Dashboard,連接企業(yè)的MCP日志流,實(shí)時(shí)顯示:
- 每個(gè)Agent的請(qǐng)求成功率/拒絕率
- 被攔截的TOP 5高危SQL模式(如
SELECT * FROM auth.*) - 新增Agent的Capability變更審計(jì)
不賣License,按Agent數(shù)量月付($49/Agent/月)。
4. MCP安全測(cè)試套件
開源的mcp-pentest工具,模擬攻擊者行為:
# 測(cè)試是否允許跨表查詢
mcp-pentest --url https://mcp.example.com --agent agent-1 --test cross-table
# 測(cè)試是否攔截危險(xiǎn)函數(shù)
mcp-pentest --url https://mcp.example.com --agent agent-1 --test pg_read_file報(bào)告直接輸出Markdown,附修復(fù)建議鏈接。
現(xiàn)在該做什么
如果你正在用Supabase MCP插件:
- 立刻停用公網(wǎng)訪問:用Cloudflare Tunnel或VPC Peering隔離MCP Server
- 檢查所有Agent注冊(cè)代碼:確認(rèn)Capability聲明已寫入,并非空數(shù)組
- 部署SQL解析中間件:哪怕先用正則粗篩
SELECT \*和DROP - 打開PostgreSQL日志:設(shè)置
log_statement = 'mod',監(jiān)控異常大查詢 - 刪掉
pg_read_server_files擴(kuò)展:除非業(yè)務(wù)強(qiáng)依賴,否則直接REVOKE ALL ON FUNCTION pg_read_file FROM PUBLIC;
安全不是功能列表里的最后一項(xiàng)。當(dāng)Agent能執(zhí)行任意SQL時(shí),數(shù)據(jù)庫就不再是你的。