一区二区三区在线观看视频-精品蜜桃一区二区三区-成人在线视频播放-日日干视频-欧美精品999-国产不卡视频在线观看-欧美精品久久久久久久久-日韩欧美一区在线-国产精品12-国产免费播放-色综合a-亚洲一卡二卡在线-天天操天天碰-jizz俄罗斯-亚洲三级伦理-韩国91视频-免费成人美女女电影-一区不卡在线观看-久久精品久久99-成人福利网站在线观看-国产色视频在线播放-最新日韩视频在线观看-国产一区欧美日韩-屁屁影院一区二区三区-亚洲精选视频在线

?? MCP生態(tài)

MCP協(xié)議安全漏洞解析:Supabase數(shù)據(jù)泄露源于默認(rèn)配置與調(diào)試模式風(fēng)險(xiǎn)

發(fā)布時(shí)間:2026-04-14 分類(lèi): MCP生態(tài)
摘要:# MCP協(xié)議安全:Supabase那次數(shù)據(jù)泄露是怎么發(fā)生的 ## 一次配置失誤,導(dǎo)致全庫(kù)暴露 Hacker News上有人貼出Supabase項(xiàng)目中MCP Server的訪問(wèn)日志截圖:一個(gè)未認(rèn)證的IP直接執(zhí)行了`SELECT * FROM users`,接著是`SELECT * FROM payments`,最后是整庫(kù)導(dǎo)出。根源不是協(xié)議本身有后門(mén),而是MCP Server啟動(dòng)時(shí)用了默認(rèn)...

封面

# MCP協(xié)議安全:Supabase那次數(shù)據(jù)泄露是怎么發(fā)生的

## 一次配置失誤,導(dǎo)致全庫(kù)暴露

Hacker News上有人貼出Supabase項(xiàng)目中MCP Server的訪問(wèn)日志截圖:一個(gè)未認(rèn)證的IP直接執(zhí)行了`SELECT * FROM users`,接著是`SELECT * FROM payments`,最后是整庫(kù)導(dǎo)出。根源不是協(xié)議本身有后門(mén),而是MCP Server啟動(dòng)時(shí)用了默認(rèn)配置,且沒(méi)關(guān)掉調(diào)試模式——`mcp-server --dev --bind 0.0.0.0:6543`,監(jiān)聽(tīng)了所有網(wǎng)卡,權(quán)限策略文件壓根沒(méi)加載。

這事不新鮮。MCP協(xié)議設(shè)計(jì)上支持細(xì)粒度控制,但默認(rèn)行為偏向開(kāi)發(fā)友好:開(kāi)箱即用,零配置啟動(dòng)。問(wèn)題出在沒(méi)人告訴開(kāi)發(fā)者——這“零配置”等于“零防護(hù)”。

## MCP協(xié)議本身不危險(xiǎn),危險(xiǎn)的是默認(rèn)值

### 它長(zhǎng)什么樣

MCP(Multi-Cloud Protocol)本質(zhì)是一套定義數(shù)據(jù)代理行為的規(guī)范,不是某個(gè)具體軟件。實(shí)際落地靠三類(lèi)組件協(xié)同:

- **MCP Server**:接收請(qǐng)求、執(zhí)行查詢、返回結(jié)果。它不存數(shù)據(jù),只代理訪問(wèn)后端數(shù)據(jù)庫(kù)(PostgreSQL、MySQL等)。
- **MCP Agent**:部署在業(yè)務(wù)服務(wù)側(cè),把本地?cái)?shù)據(jù)按MCP格式打包發(fā)給Server,或從Server拉取數(shù)據(jù)。
- **MCP Gateway**:跨云場(chǎng)景下做協(xié)議轉(zhuǎn)換和路由,比如把AWS上的Agent請(qǐng)求轉(zhuǎn)成Azure能認(rèn)的格式。

協(xié)議本身不處理身份、不加密傳輸、不校驗(yàn)簽名——這些全交給實(shí)現(xiàn)層決定。

### 漏洞不在協(xié)議,在實(shí)現(xiàn)慣性

Supabase事件里,問(wèn)題鏈條很短:

1. 運(yùn)維用`docker run -p 6543:6543 supabase/mcp-server:latest`起服務(wù),沒(méi)掛載`policy.yaml`
2. Server啟動(dòng)時(shí)發(fā)現(xiàn)策略文件缺失,自動(dòng)降級(jí)為“允許所有連接,允許所有表讀寫(xiě)”
3. 攻擊者用`nc`連上6543端口,發(fā)一條明文MCP幀:

MCP/1.0 GET /v1/query
Content-Type: application/json

{"table":"users","limit":1000}

4. Server沒(méi)校驗(yàn)來(lái)源IP、沒(méi)查T(mén)oken、沒(méi)讀策略,直接轉(zhuǎn)發(fā)給PostgreSQL,把結(jié)果原樣吐回去

根本原因就兩條:  
- 權(quán)限策略文件路徑硬編碼為`/etc/mcp/policy.yaml`,但Docker鏡像里沒(méi)這個(gè)路徑,也沒(méi)報(bào)錯(cuò)提示  
- `--dev`模式下,Server跳過(guò)所有鑒權(quán)中間件,連Basic Auth都繞過(guò)了  

這不是“漏洞”,是文檔沒(méi)寫(xiě)清的默認(rèn)行為。

## 真正管用的安全加固方式

### 別信默認(rèn)值,從啟動(dòng)參數(shù)開(kāi)始鎖死

MCP Server的安全邊界,第一道就在`docker run`或`systemd`命令里:

? 正確:顯式禁用開(kāi)發(fā)模式,強(qiáng)制加載策略,綁定本地回環(huán)

docker run \
-v $(pwd)/policy.yaml:/etc/mcp/policy.yaml \
-p 127.0.0.1:6543:6543 \
--env MCP_MODE=prod \
supabase/mcp-server:latest

? 危險(xiǎn):監(jiān)聽(tīng)0.0.0.0 + dev模式 = 公網(wǎng)裸奔

docker run -p 0.0.0.0:6543:6543 --env MCP_MODE=dev supabase/mcp-server:latest


`policy.yaml`至少要包含:

default_action: deny
rules:

  • action: allow
    methods: [GET, POST]
    paths: ["/v1/query"]
    headers:
    Authorization: "Bearer .+"
    ip_ranges: ["10.0.0.0/8", "172.16.0.0/12"]

### 身份驗(yàn)證別拼湊,用現(xiàn)成鏈路

MCP協(xié)議不規(guī)定鑒權(quán)方式,但Server實(shí)現(xiàn)必須支持標(biāo)準(zhǔn)方案:

- **JWT校驗(yàn)**:Server啟動(dòng)時(shí)指定`--jwt-key-file jwt.pub`,所有請(qǐng)求必須帶`Authorization: Bearer <token>`,token由你的Auth服務(wù)簽發(fā),payload里塞`"scope": ["read:users", "write:logs"]`
- **反向代理鑒權(quán)**:Nginx前置,用`auth_request`模塊調(diào)用你的鑒權(quán)API,只放行HTTP 200的請(qǐng)求
- **網(wǎng)絡(luò)層隔離**:Agent和Server之間走WireGuard隧道,Server防火墻只放行隧道IP段

別自己寫(xiě)Token解析邏輯。MCP Server 0.8+已內(nèi)置JWT中間件,配個(gè)公鑰就行。

### 日志不是擺設(shè),得能定位到具體請(qǐng)求

默認(rèn)日志只記“收到請(qǐng)求”,攻擊發(fā)生時(shí)你只能看到一堆`200 OK`。要改兩處:

1. 啟動(dòng)加`--log-level debug`,讓Server輸出原始MCP幀頭(含Client IP、User-Agent、完整路徑)
2. 在`policy.yaml`里加審計(jì)規(guī)則:

audit_rules:

 - match:
     method: GET
     path: "/v1/query"
     query_params: {table: ".*"}
   action: log_and_alert

這樣當(dāng)有人掃`/v1/query?table=credentials`,日志里會(huì)標(biāo)紅`AUDIT TRIGGERED`,同時(shí)發(fā)Webhook到Slack。

### 加密不是選項(xiàng),是必選項(xiàng)

- **傳輸加密**:Server必須用`--tls-cert cert.pem --tls-key key.pem`啟用HTTPS/TLS。MCP客戶端庫(kù)(如`@mcp/client`)會(huì)自動(dòng)降級(jí)到HTTP,但Server端應(yīng)直接拒絕非TLS連接(加`--require-tls`)
- **存儲(chǔ)加密**:MCP Server不碰磁盤(pán),加密責(zé)任在后端數(shù)據(jù)庫(kù)。PostgreSQL開(kāi)`pgcrypto`,字段級(jí)加密;或者用Vault做應(yīng)用層密鑰管理,Server啟動(dòng)時(shí)從Vault拉密鑰解密配置

## 工具選型:別為MCP單獨(dú)買(mǎi)套安全系統(tǒng)

MCP Server本質(zhì)是HTTP代理,現(xiàn)有安全工具鏈完全適用:

| 工具 | 為什么夠用 | 怎么集成 |
|------|------------|----------|
| **Traefik** | 自帶Let's Encrypt、JWT校驗(yàn)、IP白名單 | 把MCP Server注冊(cè)為后端服務(wù),用Middleware做鑒權(quán) |
| **OpenPolicyAgent (OPA)** | 策略即代碼,比YAML更靈活 | Server啟動(dòng)時(shí)加`--opa-url http://opa:8181`,所有請(qǐng)求先過(guò)OPA策略引擎 |
| **pgBadger** | 分析PostgreSQL日志,抓異常查詢模式 | 配置PostgreSQL的`log_statement = 'all'`,pgBadger自動(dòng)標(biāo)出`SELECT * FROM .*`高頻請(qǐng)求 |

別用所謂“MCP Security Scanner”——它只是封裝了`nmap -sV`和`curl`,掃不出策略邏輯漏洞。

## Agent開(kāi)發(fā)者該做的三件事

### 1. 請(qǐng)求頭里塞憑證,別傳明文Token

錯(cuò)誤寫(xiě)法(Token暴露在URL里):

// ? 危險(xiǎn):Token進(jìn)access log,可能被CDN緩存
fetch("https://mcp.example.com/v1/query?token=abc123&table=users")


正確寫(xiě)法(Header傳JWT,且Agent啟動(dòng)時(shí)從環(huán)境變量讀):

// ? Token存在內(nèi)存里,不進(jìn)日志
const token = process.env.MCP_JWT_TOKEN;
fetch("https://mcp.example.com/v1/query", {
method: "POST",
headers: { "Authorization": Bearer ${token} },
body: JSON.stringify({ table: "users" })
});


### 2. 所有響應(yīng)必須校驗(yàn)簽名

MCP Server可選開(kāi)啟響應(yīng)簽名(`--sign-responses`),用私鑰對(duì)響應(yīng)體哈希簽名,Header返回`X-MCP-Signature: sha256=xxx`。Agent必須用公鑰驗(yàn)簽:

// Node.js示例
const crypto = require('crypto');
const signature = res.headers.get('X-MCP-Signature');
const expected = `sha256=${crypto
.createHmac('sha256', publicKey)
.update(await res.text())
.digest('hex')}`;
if (signature !== expected) throw new Error('Response tampered');


### 3. 本地調(diào)試用Mock Server,別連生產(chǎn)

開(kāi)發(fā)時(shí)用`mcp-mock-server`替代真實(shí)Server:

npm install -g @mcp/mock-server
mcp-mock-server --policy ./dev-policy.yaml --data ./mock-data.json

它會(huì)模擬真實(shí)Server的鑒權(quán)、限流、錯(cuò)誤碼,但所有數(shù)據(jù)都在內(nèi)存里,斷網(wǎng)也能跑。

## 最后一句實(shí)在話

MCP協(xié)議的安全水位,取決于你啟動(dòng)Server時(shí)敲下的那條命令。沒(méi)有銀彈,只有檢查清單:

- [ ] `--mode prod`(不是`dev`)  
- [ ] `--policy-file`指向有效文件  
- [ ] `--tls-cert`和`--tls-key`已配置  
- [ ] 防火墻只放行Agent所在子網(wǎng)  
- [ ] PostgreSQL連接串用`sslmode=require`  

做完這些,Supabase那種泄露就不會(huì)發(fā)生在你身上。
返回首頁(yè)