分層防禦策略
中級4 分鐘閱讀更新於 2026-03-15
為 AI 應用實施縱深防禦:設計獨立的防禦層、確保正交涵蓋,並管理多層安全的複雜度。
分層防禦策略
分層防禦(縱深防禦)是處理 AI 系統中攻擊與防禦之根本不對稱最有效的策略。沒有任何單一防禦機制能涵蓋所有攻擊類型,而每一項個別防禦皆存在已知繞過技術。透過堆疊多個獨立防禦,攻擊者同時繞過所有層的機率便大幅下降——前提是這些層確實獨立。
防禦層架構
參考架構
具分層防禦的正式環境 AI 系統:
請求流程:
使用者輸入
│
▼
┌─────────────────────────────────────────────┐
│ 第 1 層:周邊防禦 │
│ ├── 速率限制 │
│ ├── 認證與授權 │
│ └── 輸入大小與格式驗證 │
└──────────────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ 第 2 層:輸入分析 │
│ ├── Prompt shield(ML 分類器) │
│ ├── Unicode/編碼正規化 │
│ └── 已知樣式黑名單 │
└──────────────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ 第 3 層:上下文安全 │
│ ├── 指令階層強制 │
│ ├── 檢索內容清理 │
│ └── 資料來源隔離 │
└──────────────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ 第 4 層:模型+推論 │
│ ├── 安全對齊模型(RLHF/DPO) │
│ ├── 含安全指令的系統提示詞 │
│ └── 溫度與取樣控制 │
└──────────────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ 第 5 層:輸出驗證 │
│ ├── 內容安全分類器 │
│ ├── PII 偵測與遮罩 │
│ ├── 工具呼叫驗證 │
│ └── 回應格式強制 │
└──────────────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ 第 6 層:交付後監控 │
│ ├── 稽核日誌 │
│ ├── 異常偵測 │
│ └── 事件告警 │
└──────────────────────┬──────────────────────┘
│
▼
回應
層的獨立性
使分層防禦有效的關鍵屬性是獨立性:一層失效不應提升另一層失效的機率。
| 獨立層 | 相關層(不良) |
|---|---|
| 關鍵詞過濾器 + 語意分類器 | 兩個不同的關鍵詞過濾器 |
| 輸入分析 + 輸出驗證 | 對輸入與輸出使用同一 ML 模型 |
| 速率限制 + 內容分類器 | 以相同資料訓練的兩個分類器 |
| 架構性約束 + ML 防禦 | ML 防禦 + ML 監控(相同模型) |
def verify_layer_independence(defense_layers, attack_set):
"""
測試防禦層是否獨立失效。
相關失效顯示共通弱點。
"""
layer_results = {}
for attack in attack_set:
for layer_name, layer in defense_layers.items():
blocked = layer.check(attack)["blocked"]
if layer_name not in layer_results:
layer_results[layer_name] = []
layer_results[layer_name].append(blocked)
# 檢查兩兩相關性
correlations = {}
layer_names = list(layer_results.keys())
for i, name_a in enumerate(layer_names):
for j, name_b in enumerate(layer_names):
if i < j:
results_a = layer_results[name_a]
results_b = layer_results[name_b]
# 計算相關性
both_fail = sum(
1 for a, b in zip(results_a, results_b)
if not a and not b
)
either_fail = sum(
1 for a, b in zip(results_a, results_b)
if not a or not b
)
correlation = both_fail / max(either_fail, 1)
correlations[f"{name_a} <-> {name_b}"] = {
"correlation": correlation,
"independent": correlation < 0.3
}
return correlations實作模式
模式 1:Fail-Open 與 Fail-Closed
每一層都必須決定遇到錯誤時的行為:
class FailClosedLayer:
"""防禦層遇到錯誤時阻擋請求。"""
def check(self, input_text):
try:
result = self.classifier.classify(input_text)
return result
except Exception as e:
# 防禦錯誤 -> 阻擋請求(保守)
logger.error(f"Defense layer error: {e}")
return {"blocked": True, "reason": "defense_error"}
class FailOpenLayer:
"""防禦層遇到錯誤時放行請求。"""
def check(self, input_text):
try:
result = self.classifier.classify(input_text)
return result
except Exception as e:
# 防禦錯誤 -> 放行(寬鬆)
logger.warning(f"Defense layer error, failing open: {e}")
return {"blocked": False, "reason": "defense_error_failopen"}模式 2:非同步與同步層
並非所有層都需要同步執行。某些層可於背景運作而不阻擋回應:
class LayeredDefenseOrchestrator:
"""編排同步與非同步防禦層。"""
def __init__(self):
self.sync_layers = [] # 回應前必須通過
self.async_layers = [] # 於背景執行
def process(self, request):
# 同步層:任一失敗即阻擋
for layer in self.sync_layers:
result = layer.check(request)
if result["blocked"]:
return self.block_response(result)
# 處理請求(產生回應)
response = self.generate_response(request)
# 同步輸出層
for layer in self.sync_output_layers:
result = layer.check(response)
if result["blocked"]:
return self.block_response(result)
# 非同步層:記錄與監控,不阻擋
for layer in self.async_layers:
self.background_queue.put((layer, request, response))
return response模式 3:升級鏈
某些攻擊值得從自動化防禦升級至人工審查:
class EscalationChain:
"""依逐步提升的審查強度路由可疑請求。"""
def __init__(self):
self.levels = [
{"name": "automated_fast", "threshold": 0.3, "action": "allow"},
{"name": "automated_deep", "threshold": 0.6, "action": "enhanced_check"},
{"name": "human_review_queue", "threshold": 0.8, "action": "queue"},
{"name": "block", "threshold": 0.95, "action": "block"},
]
def evaluate(self, request, risk_score):
"""依風險分數路由請求。"""
for level in self.levels:
if risk_score < level["threshold"]:
return {
"action": level["action"],
"level": level["name"],
"risk_score": risk_score
}
return {"action": "block", "level": "maximum", "risk_score": risk_score}效能管理
分層防禦會增加延遲,妥善管理對使用者體驗至關重要:
延遲預算配置
# 總延遲預算:2000ms(聊天應用程式典型值)
LATENCY_BUDGET = {
"perimeter": 5, # 速率限制檢查:5ms
"input_analysis": 50, # ML 分類器:50ms
"context_security": 20, # 範本檢查:20ms
"model_inference": 1500, # LLM 生成:1500ms
"output_validation": 100, # 安全分類器:100ms
"post_delivery": 0, # 非同步,不增加延遲
"overhead": 25, # 網路、序列化:25ms
"buffer": 300, # 變異緩衝:300ms
}
# 總計:2000ms平行層執行
import asyncio
async def parallel_input_defense(request):
"""平行執行獨立的輸入防禦層。"""
results = await asyncio.gather(
prompt_shield.check_async(request),
encoding_normalizer.check_async(request),
pattern_blocklist.check_async(request),
return_exceptions=True
)
# 任一層標記請求即阻擋
for result in results:
if isinstance(result, Exception):
continue # 個別層失效,繼續
if result.get("blocked"):
return result
return {"blocked": False}測試分層防禦
逐層測試
孤立測試每一層以理解其個別貢獻:
def layer_contribution_analysis(layers, attack_set):
"""衡量每層對防禦的邊際貢獻。"""
all_layers_result = evaluate_defense(layers, attack_set)
contributions = {}
for layer_name in layers:
# 移除此層並評估
remaining = {k: v for k, v in layers.items() if k != layer_name}
without_layer = evaluate_defense(remaining, attack_set)
contributions[layer_name] = {
"block_rate_with": all_layers_result["block_rate"],
"block_rate_without": without_layer["block_rate"],
"marginal_contribution": (
all_layers_result["block_rate"] -
without_layer["block_rate"]
),
"is_redundant": (
all_layers_result["block_rate"] ==
without_layer["block_rate"]
)
}
return contributions相關主題
- 防禦分類法 —— 可用防禦的目錄
- 防禦評估 —— 衡量防禦成效
- 防禦經濟學 —— 每層的成本效益
Knowledge Check
某系統有三層防禦。測試發現當第 1 層(關鍵詞過濾器)被繞過時,第 2 層(以關鍵詞過濾器訓練資料訓練的 ML 分類器)有 80% 的機率也會被繞過。問題出在哪?
參考資料
- NIST,「Framework for Improving Critical Infrastructure Cybersecurity」(2018)
- OWASP,「Defense in Depth for LLM Applications」(2024)
- Microsoft,「Azure AI Content Safety: Multi-layered defense」(2024)