運用 STRIDE 對 AI 基礎設施進行威脅建模
針對機器學習管線量身打造的 AI/ML 系統威脅建模方法論,使用 STRIDE、資料流圖與攻擊樹。
概觀
威脅建模是一套結構化流程,用以辨識安全威脅、了解其潛在衝擊,並在攻擊者利用之前優先安排緩解措施。對 AI 基礎設施而言,威脅建模尤為關鍵,因為 AI 系統具有一些傳統威脅模型無法充分涵蓋的特性:訓練資料本身即為攻擊面的一部分、模型既可能是目標也可能是武器、系統行為會隨每一次再訓練而改變,且對於學習型系統而言「預期行為」與「漏洞」之間的界線往往不甚明確。
微軟的 STRIDE 框架——Spoofing(欺騙)、Tampering(竄改)、Repudiation(否認)、Information Disclosure(資訊揭露)、Denial of Service(阻斷服務)與 Elevation of Privilege(權限提升)——提供一套系統化的威脅辨識方法,若經妥善調整亦能對應至 AI 基礎設施。然而,若未經調整直接套用 STRIDE,將錯失關鍵威脅。例如,資料投毒是一種針對訓練過程而非執行階段輸入的「Tampering」;透過推論 API 進行的模型萃取則是一種經由系統合法使用而發生的「Information Disclosure」,並非傳統意義上的漏洞。
本文提出一套完整的 AI 基礎設施威脅建模方法,將 STRIDE 擴充以納入 AI 特有的威脅類別,說明如何為常見 ML 架構繪製資料流圖,並提供執行與記錄威脅建模工作坊的範本與工具。此方法論與 NIST AI RMF、MITRE ATLAS 及 OWASP Machine Learning Security Top 10 相互對齊。
STRIDE 套用於 AI 基礎設施
AI 系統中的 Spoofing(欺騙)
Spoofing 威脅是指攻擊者偽裝成其他人或事物。在 AI 基礎設施中,欺騙呈現多種獨特形式:
| 欺騙目標 | AI 特有威脅 | 衝擊 |
|---|---|---|
| 資料來源 | 偽冒資料提供者注入訓練資料 | 模型從攻擊者控制的資料學習 |
| 模型工件 | 以攻擊者模型取代合法模型 | 推論產生攻擊者控制的輸出 |
| 推論用戶端 | 假冒已授權用戶端以存取模型 | 未授權模型存取、潛在萃取 |
| 管線階段 | 偽冒訓練管線元件 | 將惡意步驟注入 ML 管線 |
| 監控訊號 | 假造指標以隱瞞模型退化 | 掩蓋對模型進行中的攻擊 |
| 特徵來源 | 於推論時偽冒特徵儲存資料 | 操縱模型輸入以導向特定結果 |
AI 系統中的 Tampering(竄改)
Tampering 指資料在傳輸中或靜態時遭到修改。對 AI 系統而言,竄改威脅的衝擊尤為嚴重,因為它會影響模型本身的學習行為:
- 訓練資料竄改:修改訓練資料以注入後門或降低模型準確度,即典型的資料投毒攻擊。
- 模型權重竄改:直接修改儲存中的模型權重以改變推論行為。即便微小擾動也可能導致有針對性的錯誤分類。
- 特徵竄改:於特徵儲存或特徵擷取過程中修改特徵,以操縱推論結果。
- 管線竄改:修改訓練管線程式碼、超參數或組態,以產出受汙染的模型。
- 梯度竄改:在聯邦學習中,惡意參與者可送出投毒梯度,以引導全域模型偏離。
AI 系統中的 Information Disclosure(資訊揭露)
- 模型萃取:透過 API 系統性地查詢模型,以重建一份功能相當的副本。
- 訓練資料萃取:利用模型記憶能力,透過精心構造的提示詞抽取出個別訓練樣本。
- 成員推論:判斷某特定資料點是否被用於訓練。
- 架構揭露:透過 API 回應、時序側通道或中繼資料端點,擷取模型架構細節。
- 憑證揭露:AI 基礎設施元件(訓練工作、服務端點)通常具備廣泛的雲端憑證,可能透過 SSRF 等漏洞外洩。
AI 系統中的 Denial of Service(阻斷服務)
- 推論資源耗盡:構造可最大化 GPU 運算、記憶體或時間的輸入(例如 LLM 的最大長度提示詞)。
- 訓練中斷:壟斷 GPU 排程器資源、汙染訓練資料致使訓練失敗,或使訓練工作崩潰。
- 模型退化:透過資料漂移注入或策略性規避,逐步降低模型效能,使其無法使用。
- 管線 DoS:觸發過量的再訓練週期或壓垮模型登錄檔。
AI 系統中的 Elevation of Privilege(權限提升)
- GPU Pod 容器逃逸:利用 GPU 工作負載常見的高特權,攻擊容器執行環境漏洞以逃逸。
- 服務帳號濫用:訓練工作或服務 Pod 持有過度寬鬆的 IAM 角色,可用於存取無關資源。
- 管線權限提升:利用管線執行能力,以管線服務帳號的權限執行任意程式碼。
建構 AI 資料流圖
ML 系統的核心 DFD 元素
資料流圖(DFD)是 STRIDE 威脅建模的基礎。對 AI 系統而言,DFD 必須同時涵蓋傳統軟體元件與 ML 特有的資料流:
"""
AI infrastructure data flow diagram generator.
Creates structured DFD representations for threat modeling
ML systems using STRIDE.
"""
import json
from dataclasses import dataclass, field
from typing import Optional
from enum import Enum
class ElementType(Enum):
PROCESS = "process"
DATA_STORE = "data_store"
EXTERNAL_ENTITY = "external_entity"
DATA_FLOW = "data_flow"
TRUST_BOUNDARY = "trust_boundary"
class TrustZone(Enum):
EXTERNAL = "external" # Internet, end users
DMZ = "dmz" # API gateways, load balancers
INFERENCE = "inference" # Model serving
TRAINING = "training" # Training cluster
DATA = "data" # Training data storage
CONTROL = "control" # Pipeline orchestration
MONITORING = "monitoring" # Observability
REGISTRY = "registry" # Model/artifact registry
@dataclass
class DFDElement:
"""An element in the data flow diagram."""
id: str
name: str
element_type: ElementType
trust_zone: TrustZone
description: str
technologies: list[str] = field(default_factory=list)
threats: list[str] = field(default_factory=list)
@dataclass
class DataFlow:
"""A data flow between DFD elements."""
id: str
source_id: str
target_id: str
data_description: str
protocol: str
is_encrypted: bool = False
is_authenticated: bool = False
threats: list[str] = field(default_factory=list)
class AIThreatModel:
"""
Threat model for an AI infrastructure deployment.
"""
def __init__(self, system_name: str, description: str):
self.system_name = system_name
self.description = description
self.elements: dict[str, DFDElement] = {}
self.data_flows: list[DataFlow] = []
self.threats: list[dict] = []
def add_element(self, element: DFDElement) -> None:
self.elements[element.id] = element
def add_data_flow(self, flow: DataFlow) -> None:
self.data_flows.append(flow)
def apply_stride(self) -> list[dict]:
"""Systematically apply STRIDE to all elements and data flows."""
threats = []
for elem in self.elements.values():
if elem.element_type == ElementType.PROCESS:
threats.extend(self._stride_process(elem))
elif elem.element_type == ElementType.DATA_STORE:
threats.extend(self._stride_data_store(elem))
elif elem.element_type == ElementType.EXTERNAL_ENTITY:
threats.extend(self._stride_external_entity(elem))
for flow in self.data_flows:
threats.extend(self._stride_data_flow(flow))
threats.extend(self._cross_boundary_threats())
self.threats = threats
return threats
def _stride_process(self, elem: DFDElement) -> list[dict]:
"""Apply all STRIDE categories to a process element."""
threats = []
prefix = f"{elem.name} ({elem.id})"
threats.append({
"element": elem.id, "category": "Spoofing",
"threat": f"An attacker could impersonate {prefix}.",
"mitigation": "Implement mutual TLS with workload identity (SPIFFE).",
})
threats.append({
"element": elem.id, "category": "Tampering",
"threat": f"An attacker could modify the behavior of {prefix}.",
"mitigation": "Sign artifacts, use read-only filesystems, verify inputs.",
})
# Additional categories: Repudiation, Information Disclosure,
# Denial of Service, Elevation of Privilege...
return threats
# Similar helpers for data stores, external entities, data flows
# and cross-boundary trust zone crossings follow the same pattern.
def generate_report(self) -> str:
"""Generate a structured threat model report as JSON."""
if not self.threats:
self.apply_stride()
# Aggregate threats by category and AI-specific flag, return JSON.
return json.dumps({"system": self.system_name, "threats": self.threats}, indent=2)上述程式碼提供一個資料類別骨架:DFDElement 代表流程、資料儲存或外部實體;DataFlow 記錄兩個元素之間的資料移動(含加密與認證旗標);AIThreatModel 以 apply_stride 系統化地為每個元素與流套用 STRIDE 類別,並識別跨信任邊界的流動以產出威脅清單。重點在於每一類 STRIDE(對流程的欺騙、竄改、否認、資訊揭露、阻斷服務、權限提升)都有對應的緩解建議(mTLS 與 SPIFFE 工作負載身分、唯讀檔案系統、稽核日誌、速率限制與差分隱私、資源限制、最小權限非 root 容器)。
實務範例
威脅建模 LLM 推論管線
下列範例展示如何為部署於 Kubernetes GPU 節點的 LLM 推論管線建構威脅模型:
"""Threat model for an LLM inference pipeline on Kubernetes GPUs."""
def create_llm_inference_threat_model() -> "AIThreatModel":
tm = AIThreatModel(
system_name="LLM Inference Pipeline",
description=(
"Production LLM inference system serving API requests "
"through a load balancer, with model artifacts stored "
"in S3 and served via vLLM on GPU nodes."
),
)
# External entities: API clients, ML engineers
tm.add_element(DFDElement(
id="user", name="API Client",
element_type=ElementType.EXTERNAL_ENTITY,
trust_zone=TrustZone.EXTERNAL,
description="External application consuming the LLM API",
technologies=["HTTPS", "REST"],
))
# Processes: API gateway (Kong/NGINX in DMZ), vLLM inference
# server (GPU inference zone), deployment pipeline (control zone)
tm.add_element(DFDElement(
id="vllm", name="vLLM Inference Server",
element_type=ElementType.PROCESS,
trust_zone=TrustZone.INFERENCE,
description="GPU-accelerated LLM inference with PagedAttention",
technologies=["vLLM", "CUDA", "PyTorch"],
))
# Data stores: S3 model artifacts, MLflow registry, log store
tm.add_element(DFDElement(
id="s3_models", name="S3 Model Artifact Store",
element_type=ElementType.DATA_STORE,
trust_zone=TrustZone.REGISTRY,
description="Stores trained model weights and configurations",
technologies=["AWS S3", "SSE-KMS"],
))
# Data flows with encryption/authentication flags:
# - user -> gateway: HTTPS, encrypted, authenticated
# - gateway -> vLLM: HTTP/gRPC, often unencrypted (common gap)
# - s3_models -> vLLM: HTTPS, encrypted, authenticated
# - mlflow -> pipeline: webhook, often unauthenticated (gap)
# - vLLM -> logs: HTTP, unencrypted
tm.add_data_flow(DataFlow(
id="df2", source_id="gateway", target_id="vllm",
data_description="Authenticated inference requests",
protocol="HTTP/gRPC",
is_encrypted=False, # Common gap: internal traffic unencrypted
is_authenticated=False,
))
return tm此範例揭示常見缺口:叢集內部 gateway 至 vLLM 的流量通常未加密也未相互認證;MLflow 觸發部署的 webhook 常未認證,讓攻擊者得以注入惡意部署;推論日誌以明文傳送至 Elasticsearch,含有提示詞與回應,可能導致 PII 外洩。套用 STRIDE 後,此模型會自動辨識這些缺口並對應至 AML.T0020(訓練資料投毒)、AML.T0010(模型工件替換)與 AML.T0024(模型萃取)等 ATLAS 手法。
為 AI 調整的 DREAD 風險評分
DREAD(Damage、Reproducibility、Exploitability、Affected users、Discoverability)可透過在每個維度納入 AI 特有因子,加以調整以適用於 AI 系統:
"""DREAD scoring adapted for AI infrastructure threats."""
@dataclass
class AIThreatScore:
threat_name: str
atlas_technique: Optional[str]
# Standard DREAD dimensions (1-10)
damage: int
reproducibility: int
exploitability: int
affected_users: int
discoverability: int
# AI-specific adjustment factors (1.0-2.0)
model_impact: float = 1.0
data_sensitivity: float = 1.0
detection_difficulty: float = 1.0
@property
def base_dread_score(self) -> float:
return (self.damage + self.reproducibility + self.exploitability
+ self.affected_users + self.discoverability) / 5.0
@property
def ai_adjusted_score(self) -> float:
"""Geometric mean of AI factors prevents extreme values."""
base = self.base_dread_score
ai_mult = (self.model_impact * self.data_sensitivity
* self.detection_difficulty) ** (1/3)
return min(10.0, base * ai_mult)
@property
def priority(self) -> str:
s = self.ai_adjusted_score
if s >= 8.0: return "CRITICAL"
if s >= 6.0: return "HIGH"
if s >= 4.0: return "MEDIUM"
if s >= 2.0: return "LOW"
return "INFO"關鍵設計在於 AI 調整係數以幾何平均組合,避免極端值主導;資料投毒因同時具備高 model_impact、高 data_sensitivity 與高 detection_difficulty,通常升級為 CRITICAL;反之 TorchServe 管理 API 的 RCE 即便是基礎設施層威脅,因其可直接接管推論節點,仍會取得 CRITICAL 評分。常見範例包括:透過 S3 寫入權限進行的訓練資料投毒(AML.T0020,CRITICAL)、透過推論 API 的模型萃取(AML.T0024,HIGH)、TorchServe 管理 API 的 RCE(AML.T0010,CRITICAL)、租戶間 GPU 記憶體側通道(AML.T0024,HIGH)。
威脅建模工作坊的引導
進行有效的 AI 威脅建模工作坊需結合安全專業與 ML 工程知識。以下是引導此類工作坊的結構化作法:
參與者:至少包含一位熟悉 STRIDE 的安全工程師、一位了解訓練管線的 ML 工程師、一位管理部署平台的基礎設施工程師,以及一位能評估業務衝擊的產品負責人。若為 LLM 系統,應納入熟悉提示詞工程與模型行為的成員。
前置作業:會議前依架構文件與訪談彙整一份 DFD 草稿。DFD 應涵蓋所有資料流,包含訓練資料汲取、模型工件移動、推論請求流與遙測收集。於會議前一週將 DFD 分送給參與者檢視。
議程結構(通常 2-4 小時):
- 檢視並修訂 DFD(30 分鐘)
- 逐一檢視每個元素與資料流,套用 STRIDE(90-120 分鐘)
- 以 DREAD 或 CVSS 對辨識到的威脅評分(30 分鐘)
- 確認優先緩解措施(30 分鐘)
常見盲點應在會議中特別追問:
- 「若有人修改訓練資料會發生什麼事?」(團隊常預設資料完整性)
- 「多次查詢模型後可以學到什麼?」(模型萃取)
- 「訓練工作可存取哪些憑證?」(爆炸半徑)
- 「受汙染的模型能否透過其輸出外洩資料?」(模型作為外洩通道)
AI 的 STRIDE 威脅目錄
下表彙整 AI 基礎設施特有的關鍵 STRIDE 威脅(超出傳統 IT 威脅範疇):
| STRIDE 類別 | AI 威脅 | ATLAS 手法 | 優先等級 |
|---|---|---|---|
| Spoofing | 偽冒資料來源注入投毒資料 | AML.T0020 | Critical |
| Spoofing | 替換登錄檔中的模型工件 | AML.T0010 | Critical |
| Tampering | 修改儲存中的訓練資料 | AML.T0020 | Critical |
| Tampering | 於傳輸過程中變造模型權重 | AML.T0010 | High |
| Tampering | 於推論時操縱特徵值 | AML.T0043 | High |
| Repudiation | 否認造成事件的模型部署 | - | Medium |
| Info Disclosure | 透過推論 API 萃取模型 | AML.T0024 | High |
| Info Disclosure | 從模型中萃取訓練資料 | AML.T0024 | High |
| Info Disclosure | 租戶間 GPU 記憶體洩漏 | AML.T0024 | High |
| DoS | 透過對抗性提示詞耗盡資源 | AML.T0029 | High |
| DoS | 以資料汙染中斷訓練 | - | Medium |
| EoP | 自特權 GPU Pod 的容器逃逸 | - | Critical |
| EoP | 經模型反序列化進行管線 RCE | AML.T0010 | Critical |
防禦與緩解
及早且反覆進行威脅建模:在設計階段、部署前以及每次架構重大變更後,均應對 AI 系統執行威脅建模。將 ML 工程師納入威脅建模工作坊——他們了解資料流與模型行為,這些往往是安全團隊會遺漏之處。
系統化地採用 STRIDE-per-Element:逐一走訪每個 DFD 元素與每條資料流,套用每個 STRIDE 類別。此結構化方式可防止遺漏那些看似不太可能卻具高衝擊的威脅。
優先處理 AI 特有威脅:一般 IT 威脅建模可能將「資料儲存竄改」評為中度風險;但對 AI 系統而言,訓練資料竄改是關鍵,因為它能以難以偵測的方式悄悄汙染模型行為。
對應至 MITRE ATLAS:將辨識到的威脅與 ATLAS 手法交叉比對,以確保完整性並利用社群對真實世界攻擊的知識。
記錄假設與信任邊界:明確陳述何者可信、何者不可信。AI 系統中常見的未明言假設(如「訓練資料可信」、「S3 中的模型工件未被修改」)往往正是安全缺口的根本原因。
再訓練後重新檢視:每一次模型再訓練週期,若訓練資料、管線或超參數有所變動,都可能引入新威脅。應相應更新威脅模型。
自動化威脅模型驗證:利用結構化的威脅模型輸出,自動產生安全測試案例。對每個具備可測程序的威脅,建立自動化測試以驗證其緩解措施是否到位且有效。將這些測試納入 CI/CD 並排程定期執行,以偵測回歸。這能將威脅模型由靜態文件轉化為持續對實際系統驗證的活體安全規格。
在威脅模型中納入對抗式 ML:傳統 STRIDE 聚焦於基礎設施層威脅。對 AI 系統而言,應明確地將規避、投毒與模型反演等對抗式 ML 攻擊納入威脅模型。此類攻擊針對模型習得的行為而非基礎設施,其緩解方式(穩健訓練、輸入驗證、輸出擾動)亦與傳統安全控制不同。
參考資料
- Shostack, A. (2014). "Threat Modeling: Designing for Security." Wiley. ISBN: 978-1118809990.
- MITRE. (2024). "ATLAS: Adversarial Threat Landscape for AI Systems." https://atlas.mitre.org/
- Microsoft. (2024). "Threat Modeling for AI/ML Systems." https://learn.microsoft.com/en-us/security/engineering/threat-modeling-aiml
- NIST. (2023). "AI Risk Management Framework (AI RMF 1.0)." https://airc.nist.gov/AI_RMF_Interactivity/
- OWASP. (2025). "OWASP Machine Learning Security Top 10." https://owasp.org/www-project-machine-learning-security-top-10/