在上一章,我們示範了 MCP 端點如果沒有防護,攻擊者可以直接送入惡意 payload,導致 LLM 或資料庫被濫用。
這一章,我們要加上 輸入驗證 (Input Validation),讓 n8n 在處理請求前,先檢查資料是否合法。
如果沒有阻擋惡意指令,攻擊者可能注入以下內容:
DROP TABLE
<script>
exec()
若未過濾,系統就會直接執行,造成嚴重後果。
其他風險包含:
在 Webhook 之後加一個 Function 節點,專門用來檢查輸入是否合法。
const headers = $json.headers;
const body = $json.body;
const prompt = body?.prompt || "";
// === 防禦策略 #1:API Key 驗證 ===
const apiKey = headers["x-api-key"];
const validKey = $env.API_KEY;
if (apiKey !== validKey) {
return [{
json: {
statusCode: 401,
responseBody: {
error: "Unauthorized",
message: "Invalid API Key"
},
valid: false
}
}];
}
// === 防禦策略 #2:輸入驗證 ===
const blacklist = ["drop table", "exec(", "<script>", "rm -rf", "shutdown"];
// 長度限制
if (prompt.length > 500) {
return [{
json: {
statusCode: 400,
responseBody: {
error: "Invalid input",
message: "Prompt too long"
},
valid: false
}
}];
}
// 黑名單檢查
for (const keyword of blacklist) {
if (prompt.toLowerCase().includes(keyword)) {
return [{
json: {
statusCode: 400,
responseBody: {
error: "Invalid input",
message: `Forbidden keyword: ${keyword}`
},
valid: false
}
}];
}
}
// === 通過驗證 ===
return [{
json: {
statusCode: 200,
responseBody: {
message: "Authorized & Valid request",
body
},
valid: true
}
}];
curl -X POST "http://your-n8n-domain/webhook/hello" \
-H "x-api-key: webhook_text_123" -H "Content-Type: application/json" \
-d '{"prompt":"DROP TABLE users; --"}'
→ 會回傳 400 Invalid input
curl -X POST "http://your-n8n-domain/webhook/hello" \
-H "x-api-key: webhook_text_123" -H "Content-Type: application/json" \
-d '{"prompt":"Hello World"}'
→ 成功通過驗證
狀況 | 攻擊者行為 | 系統反應 |
---|---|---|
沒有輸入驗證 | {"prompt":"DROP TABLE users"} |
Payload 進入後端,可能破壞資料庫 |
有輸入驗證 | {"prompt":"DROP TABLE users"} |
立即被攔截,回傳 400,攻擊失敗 |
輸入驗證是 第二道防線。
即使攻擊者繞過 API Key,也會因為輸入格式檢查而被擋下。
這大幅降低 Prompt Injection、DoS 與 SQL Injection 的成功率。