[OWASP] 002 AI Agent 安全開發指南:OWASP 九大風險與八大防護實踐(OWASP AI Agent Security Cheat Sheet)

AI Agent 安全開發指南

基於 OWASP AI Agent Security Cheat Sheet


前言:為什麼 AI Agent 安全至關重要

AI Agent 是由大型語言模型(LLM)驅動的自主系統,能夠進行推理、規劃、使用工具、維護記憶,並採取行動來達成目標。這種擴展的能力引入了超越傳統 LLM 提示注入的獨特安全風險。

隨著 AI Agent 在企業應用中的普及,開發者必須了解並防範這些新興威脅。本指南將幫助您建立安全的 AI Agent 架構,最小化攻擊面。


主要安全風險

在開發 AI Agent 時,您需要特別關注以下九大風險類別:

1. 提示注入攻擊(Prompt Injection)

惡意指令通過使用者輸入或外部資料來源(網站、文件、電子郵件)注入,劫持 Agent 行為。這包括:

  • 直接注入:使用者直接在輸入中嵌入惡意指令
  • 間接注入:通過 Agent 讀取的外部資料(如網頁、文件)注入惡意指令

2. 工具濫用與權限提升(Tool Abuse & Privilege Escalation)

Agent 利用權限過大的工具執行非預期的操作或存取未授權的資源。攻擊者可能誘導 Agent 使用工具來:

  • 存取敏感檔案系統
  • 執行未授權的資料庫操作
  • 呼叫受限的 API

3. 資料外洩(Data Exfiltration)

敏感資訊通過以下管道洩露:

  • 工具呼叫參數
  • API 請求
  • Agent 輸出回應
  • 日誌記錄

4. 記憶體污染(Memory Poisoning)

惡意資料持久化到 Agent 記憶體中,可能:

  • 影響未來的會話
  • 影響其他使用者
  • 建立持久的後門

5. 目標劫持(Goal Hijacking)

操縱 Agent 目標使其服務於攻擊者目的,同時看起來合法。Agent 可能被誘導:

  • 執行與原始任務無關的操作
  • 優先處理攻擊者的指令
  • 忽略安全限制

6. 過度自主(Excessive Autonomy)

Agent 在沒有適當人工監督的情況下執行高影響操作,可能導致:

  • 不可逆的資料變更
  • 財務損失
  • 聲譽損害

7. 級聯故障(Cascading Failures)

多 Agent 系統中被入侵的 Agent 將攻擊傳播到其他 Agent,造成:

  • 系統性安全漏洞
  • 大規模資料洩露
  • 服務中斷

8. 錢包拒絕服務(Denial of Wallet, DoW)

通過無限制的 Agent 迴圈造成過高的 API/運算成本的攻擊:

  • 無限迴圈消耗 Token
  • 大量不必要的工具呼叫
  • 惡意觸發昂貴的運算操作

9. 敏感資料暴露(Sensitive Data Exposure)

個人識別資訊(PII)、憑證或機密資料意外包含在:

  • Agent 上下文
  • 日誌記錄
  • 錯誤訊息
  • 除錯輸出

最佳安全實踐

1. 工具安全與最小權限原則

這是 AI Agent 安全的第一道防線。確保每個 Agent 只能存取完成其特定任務所需的最少工具和權限。

核心原則:

  • 只授予 Agent 特定任務所需的最少工具
  • 實施每個工具的權限範圍(唯讀 vs. 寫入、特定資源)
  • 對不同信任等級使用不同的工具集(例如:內部 vs. 面向使用者的 Agent)
  • 敏感操作需要明確的工具授權

❌ 錯誤示範:權限過大的工具配置

# 危險:Agent 具有無限制的 shell 存取權限
tools = [
    {
        "name": "execute_command",
        "description": "Execute any shell command",
        "allowed_commands": "*"  # 無限制!
    }
]

✅ 正確示範:使用允許清單限制範圍

# 安全:限制為特定、安全的操作
tools = [
    {
        "name": "file_reader",
        "description": "Read files from the reports directory",
        "allowed_paths": ["/app/reports/*"],
        "allowed_operations": ["read"],
        "blocked_patterns": ["*.env", "*.key", "*.pem", "*secret*"]
    }
]

工具授權中介軟體範例

from functools import wraps

SENSITIVE_TOOLS = ["send_email", "execute_code", "database_write", "file_delete"]

def require_confirmation(func):
    @wraps(func)
    async def wrapper(tool_name, params, context):
        if tool_name in SENSITIVE_TOOLS:
            if not context.get("user_confirmed"):
                return {
                    "status": "pending_confirmation",
                    "message": f"Action '{tool_name}' requires user approval",
                    "params": sanitize_for_display(params)
                }
        return await func(tool_name, params, context)
    return wrapper

2. 輸入驗證與提示注入防禦

所有外部資料都應被視為不可信任,必須在納入 Agent 上下文之前進行驗證和清理。

核心原則:

  • 將所有外部資料視為不可信任(使用者訊息、檢索的文件、API 回應、電子郵件)
  • 在將外部內容納入 Agent 上下文之前實施輸入清理
  • 使用分隔符號和清晰的邊界區分指令和資料
  • 對已知的注入模式套用內容過濾
  • 考慮使用獨立的 LLM 呼叫來驗證/摘要不可信任的內容

建議的防禦層級:

┌─────────────────────────────────────────┐
│         使用者輸入 / 外部資料            │
└─────────────────┬───────────────────────┘
                  ▼
┌─────────────────────────────────────────┐
│       第一層:格式驗證與清理             │
│   - 長度限制                            │
│   - 特殊字元過濾                        │
│   - 編碼驗證                            │
└─────────────────┬───────────────────────┘
                  ▼
┌─────────────────────────────────────────┐
│       第二層:注入模式偵測               │
│   - 已知攻擊模式比對                    │
│   - 指令分隔符號偵測                    │
│   - 異常內容標記                        │
└─────────────────┬───────────────────────┘
                  ▼
┌─────────────────────────────────────────┐
│       第三層:上下文隔離                 │
│   - 明確的資料/指令邊界                 │
│   - 信任等級標記                        │
│   - 獨立的驗證 LLM 呼叫                 │
└─────────────────┬───────────────────────┘
                  ▼
┌─────────────────────────────────────────┐
│            Agent 上下文                  │
└─────────────────────────────────────────┘

3. 記憶體與上下文安全

Agent 的記憶體系統可能成為攻擊者的目標,用於持久化惡意資料或竊取敏感資訊。

核心原則:

  • 在儲存到 Agent 記憶體之前驗證和清理資料
  • 在使用者/會話之間實施記憶體隔離
  • 設定記憶體過期時間和大小限制
  • 在持久化之前審核記憶體內容是否有敏感資料
  • 對長期記憶使用加密完整性檢查

❌ 錯誤示範:未驗證的記憶體儲存

# 危險:將任意使用者輸入儲存到持久記憶體
def save_memory(agent, user_message, assistant_response):
    agent.memory.add({
        "user": user_message,  # 可能包含注入 payload
        "assistant": assistant_response,
        "timestamp": datetime.now()
    })

✅ 正確示範:經過驗證和隔離的記憶體

import hashlib
from datetime import datetime, timedelta

class SecureAgentMemory:
    MAX_MEMORY_ITEMS = 100
    MAX_ITEM_LENGTH = 5000
    MEMORY_TTL_HOURS = 24

    def __init__(self, user_id: str, encryption_key: bytes):
        self.user_id = user_id
        self.encryption_key = encryption_key
        self.memories = []

    def add(self, content: str, memory_type: str = "conversation"):
        # 驗證內容
        if len(content) > self.MAX_ITEM_LENGTH:
            content = content[:self.MAX_ITEM_LENGTH]

        # 掃描敏感資料模式
        if self._contains_sensitive_data(content):
            content = self._redact_sensitive_data(content)

        # 掃描注入模式
        content = self._sanitize_injection_attempts(content)

        # 建立具有完整性檢查的記憶體項目
        entry = {
            "content": content,
            "type": memory_type,
            "timestamp": datetime.utcnow().isoformat(),
            "user_id": self.user_id,
            "checksum": self._compute_checksum(content)
        }

        self.memories.append(entry)
        self._enforce_limits()

    def _contains_sensitive_data(self, content: str) -> bool:
        sensitive_patterns = [
            r'\b\d{3}-\d{2}-\d{4}\b',  # SSN
            r'\b\d{16}\b',              # 信用卡
            r'password\s*[:=]\s*\S+',   # 密碼
            r'api[_-]?key\s*[:=]\s*\S+' # API 金鑰
        ]
        return any(re.search(p, content, re.I) for p in sensitive_patterns)

    def _compute_checksum(self, content: str) -> str:
        return hashlib.sha256(
            (content + self.user_id).encode() + self.encryption_key
        ).hexdigest()[:16]

4. 人機協作控制(Human-in-the-Loop)

對於高影響或不可逆的操作,必須確保有人工審核和批准的機制。

核心原則:

  • 高影響或不可逆操作需要明確批准
  • 在執行前實施操作預覽
  • 根據操作風險等級設定自主權邊界
  • 提供 Agent 決策和操作的清晰稽核軌跡
  • 允許使用者中斷和回滾 Agent 操作

風險等級分類

風險等級 操作類型 處理方式
低(LOW) 讀取操作、安全查詢 自動批准
中(MEDIUM) 寫入操作、API 呼叫 記錄並監控
高(HIGH) 財務、刪除、外部通訊 需要人工審核
嚴重(CRITICAL) 不可逆、安全敏感操作 強制人工批准

操作分類與批准流程範例

from enum import Enum
from dataclasses import dataclass

class RiskLevel(Enum):
    LOW = "low"           # 讀取操作、安全查詢
    MEDIUM = "medium"     # 寫入操作、API 呼叫
    HIGH = "high"         # 財務、刪除、外部通訊
    CRITICAL = "critical" # 不可逆、安全敏感

ACTION_RISK_MAPPING = {
    "search_documents": RiskLevel.LOW,
    "read_file": RiskLevel.LOW,
    "write_file": RiskLevel.MEDIUM,
    "send_email": RiskLevel.HIGH,
    "execute_code": RiskLevel.HIGH,
    "database_delete": RiskLevel.CRITICAL,
    "transfer_funds": RiskLevel.CRITICAL,
}

@dataclass
class PendingAction:
    action_id: str
    tool_name: str
    parameters: dict
    risk_level: RiskLevel
    explanation: str

class HumanInTheLoopController:
    def __init__(self, auto_approve_threshold: RiskLevel = RiskLevel.LOW):
        self.auto_approve_threshold = auto_approve_threshold
        self.pending_actions = {}

    async def request_action(self, tool_name: str, params: dict, 
                            explanation: str) -> dict:
        risk_level = ACTION_RISK_MAPPING.get(tool_name, RiskLevel.HIGH)

        # 自動批准低風險操作
        if risk_level.value <= self.auto_approve_threshold.value:
            return {"approved": True, "auto": True}

        # 排隊等待人工審核
        action = PendingAction(
            action_id=generate_uuid(),
            tool_name=tool_name,
            parameters=self._sanitize_params_for_display(params),
            risk_level=risk_level,
            explanation=explanation
        )

        self.pending_actions[action.action_id] = action

        return {
            "approved": False,
            "pending": True,
            "action_id": action.action_id,
            "requires": "human_approval",
            "risk_level": risk_level.value,
            "preview": self._generate_action_preview(action)
        }

5. 輸出驗證與防護欄

Agent 的輸出必須經過驗證,以防止敏感資料洩露和惡意操作執行。

核心原則:

  • 在執行或顯示前驗證 Agent 輸出
  • 實施敏感資料洩露的輸出過濾
  • 盡可能使用具有 schema 驗證的結構化輸出
  • 設定輸出操作的邊界(速率限制、範圍限制)
  • 對生成的回應套用內容安全過濾器

輸出驗證管道範例

from pydantic import BaseModel, validator
from typing import Optional, List

class AgentToolCall(BaseModel):
    tool_name: str
    parameters: dict
    reasoning: Optional[str]

    @validator('tool_name')
    def validate_tool_allowed(cls, v):
        allowed_tools = ["search", "read_file", "calculator", "get_weather"]
        if v not in allowed_tools:
            raise ValueError(f"Tool '{v}' is not in allowed list")
        return v

    @validator('parameters')
    def validate_no_sensitive_data(cls, v):
        sensitive_patterns = [
            r'api[_-]?key', r'password', r'secret', r'token',
            r'credential', r'private[_-]?key'
        ]
        params_str = json.dumps(v).lower()
        for pattern in sensitive_patterns:
            if re.search(pattern, params_str):
                raise ValueError("Parameters contain potentially sensitive data")
        return v

class OutputGuardrails:
    def __init__(self):
        self.pii_patterns = self._load_pii_patterns()
        self.rate_limiter = RateLimiter(max_calls=100, window_seconds=60)

    async def validate_output(self, agent_output: dict) -> dict:
        # 檢查速率限制
        if not self.rate_limiter.allow():
            raise RateLimitExceeded("Agent action rate limit exceeded")

        # 驗證結構
        if "tool_calls" in agent_output:
            for call in agent_output["tool_calls"]:
                validated = AgentToolCall(**call)

        # 從回應中過濾 PII
        if "response" in agent_output:
            agent_output["response"] = self._filter_pii(agent_output["response"])

        # 檢查資料外洩模式
        if self._detect_exfiltration_attempt(agent_output):
            raise SecurityViolation("Potential data exfiltration detected")

        return agent_output

    def _detect_exfiltration_attempt(self, output: dict) -> bool:
        """偵測通過工具呼叫外洩資料的嘗試"""
        suspicious_patterns = [
            # 在 URL 中編碼敏感資料
            lambda o: "http" in str(o) and any(
                p in str(o).lower() for p in ["base64", "encode", "password"]
            ),
            # webhook/API 呼叫中的大量資料
            lambda o: o.get("tool_name") in ["http_request", "webhook"] and 
                     len(str(o.get("parameters", ""))) > 10000,
        ]
        return any(pattern(output) for pattern in suspicious_patterns)

6. 監控與可觀測性

全面的監控系統是偵測和回應安全事件的關鍵。

核心原則:

  • 記錄所有 Agent 決策、工具呼叫和結果
  • 實施異常行為的異常偵測
  • 追蹤每個會話/使用者的 Token 使用量和成本
  • 設定安全相關事件的警報
  • 維護合規和鑑識的稽核軌跡

建議的異常偵測閾值

指標 建議閾值
每分鐘工具呼叫次數 30
失敗的工具呼叫次數 5
注入嘗試次數 1(立即警報)
敏感資料存取次數 3
每會話成本(美元) $10.00

Agent 監控範例

import structlog
from dataclasses import dataclass
from typing import Dict, Any, Optional
from datetime import datetime

logger = structlog.get_logger()

@dataclass
class AgentSecurityEvent:
    event_type: str
    severity: str  # INFO, WARNING, CRITICAL
    agent_id: str
    session_id: str
    user_id: str
    timestamp: datetime
    details: Dict[str, Any]
    tool_name: Optional[str] = None

class AgentMonitor:
    ANOMALY_THRESHOLDS = {
        "tool_calls_per_minute": 30,
        "failed_tool_calls": 5,
        "injection_attempts": 1,
        "sensitive_data_access": 3,
        "cost_per_session_usd": 10.0,
    }

    def __init__(self, agent_id: str):
        self.agent_id = agent_id
        self.session_metrics = {}
        self.alert_handlers = []

    async def log_tool_call(self, session_id: str, tool_name: str, 
                           params: dict, result: dict, user_id: str):
        # 記錄前遮蔽敏感資料
        safe_params = self._redact_sensitive(params)
        safe_result = self._redact_sensitive(result)

        event = AgentSecurityEvent(
            event_type="tool_call",
            severity="INFO",
            agent_id=self.agent_id,
            session_id=session_id,
            user_id=user_id,
            timestamp=datetime.utcnow(),
            tool_name=tool_name,
            details={
                "parameters": safe_params,
                "result_status": result.get("status"),
                "execution_time_ms": result.get("execution_time_ms"),
            }
        )

        await self._emit_event(event)
        await self._check_anomalies(session_id, event)

    def _redact_sensitive(self, data: dict) -> dict:
        """從日誌資料中遮蔽敏感欄位"""
        sensitive_keys = {"password", "api_key", "token", "secret", "credential"}

        def redact(obj):
            if isinstance(obj, dict):
                return {
                    k: "***REDACTED***" if k.lower() in sensitive_keys else redact(v)
                    for k, v in obj.items()
                }
            elif isinstance(obj, list):
                return [redact(i) for i in obj]
            return obj

        return redact(data)

7. 多 Agent 系統安全

當多個 Agent 協作時,需要特別注意防止攻擊在 Agent 之間傳播。

核心原則:

  • 在 Agent 之間實施信任邊界
  • 驗證和清理 Agent 間通訊
  • 防止通過 Agent 鏈的權限提升
  • 隔離 Agent 執行環境
  • 套用熔斷器以防止級聯故障

Agent 信任等級定義

信任等級 說明
UNTRUSTED (0) 不受信任的外部 Agent,需要完全驗證
INTERNAL (1) 內部 Agent,有基本存取權限
PRIVILEGED (2) 具有提升權限的 Agent
SYSTEM (3) 系統級 Agent,具有完全存取權限

安全的多 Agent 通訊範例

from typing import Optional, List
import jwt
from datetime import datetime, timedelta
from enum import Enum

class AgentTrustLevel(Enum):
    UNTRUSTED = 0
    INTERNAL = 1
    PRIVILEGED = 2
    SYSTEM = 3

class SecureAgentBus:
    """多 Agent 系統的安全通訊層"""

    def __init__(self, signing_key: bytes):
        self.signing_key = signing_key
        self.agent_registry = {}
        self.circuit_breakers = {}

    def register_agent(self, agent_id: str, trust_level: AgentTrustLevel,
                       allowed_recipients: List[str]):
        self.agent_registry[agent_id] = {
            "trust_level": trust_level,
            "allowed_recipients": allowed_recipients,
            "allowed_message_types": self._get_allowed_types(trust_level)
        }
        self.circuit_breakers[agent_id] = CircuitBreaker(
            failure_threshold=5,
            recovery_timeout=60
        )

    async def send_message(self, sender_id: str, recipient_id: str,
                          message_type: str, payload: dict) -> dict:
        # 驗證發送者
        sender = self.agent_registry.get(sender_id)
        if not sender:
            raise SecurityViolation(f"Unknown sender agent: {sender_id}")

        # 檢查熔斷器
        if self.circuit_breakers[sender_id].is_open:
            raise CircuitBreakerOpen(f"Agent {sender_id} is temporarily blocked")

        # 驗證接收者授權
        if recipient_id not in sender["allowed_recipients"]:
            raise SecurityViolation("Sender not authorized to message recipient")

        # 清理 payload
        sanitized_payload = self._sanitize_payload(payload, sender["trust_level"])

        # 建立簽署的訊息
        signed_message = {
            "sender": sender_id,
            "recipient": recipient_id,
            "type": message_type,
            "payload": sanitized_payload,
            "timestamp": datetime.utcnow().isoformat(),
            "signature": self._sign_message(sender_id, recipient_id, 
                                           message_type, sanitized_payload)
        }

        return signed_message

    async def receive_message(self, recipient_id: str, message: dict) -> dict:
        # 驗證簽章
        if not self._verify_signature(message):
            raise SecurityViolation("Invalid message signature")

        # 檢查訊息新鮮度(防止重播攻擊)
        msg_time = datetime.fromisoformat(message["timestamp"])
        if (datetime.utcnow() - msg_time) > timedelta(minutes=5):
            raise SecurityViolation("Message expired (possible replay attack)")

        return message["payload"]

8. 資料保護與隱私

遵循資料最小化原則,確保敏感資料得到適當保護。

核心原則:

  • 最小化 Agent 上下文中的敏感資料
  • 實施資料分類和處理規則
  • 對靜態和傳輸中的資料套用加密
  • 執行資料保留和刪除政策
  • 符合隱私法規(GDPR、CCPA 等)

資料分類與處理建議

分類 範例 處理方式
RESTRICTED SSN、信用卡、健康資料 完全遮蔽
CONFIDENTIAL 薪資、API 金鑰、密碼 部分遮蔽
INTERNAL 內部文件、草稿 正常處理,記錄時遮蔽
PUBLIC 公開資訊 正常處理

資料分類與處理範例

from enum import Enum
import re

class DataClassification(Enum):
    PUBLIC = "public"
    INTERNAL = "internal"
    CONFIDENTIAL = "confidential"
    RESTRICTED = "restricted"  # PII、財務、健康

class DataProtectionPolicy:
    def __init__(self):
        self.classification_rules = []
        self.handling_rules = {}

    def classify_data(self, data: str, context: dict) -> DataClassification:
        """根據內容模式自動分類資料"""
        patterns = {
            DataClassification.RESTRICTED: [
                r'\b\d{3}-\d{2}-\d{4}\b',      # SSN
                r'\b\d{16}\b',                  # 信用卡
                r'\b[A-Z]{2}\d{6,9}\b',         # 護照
                r'diagnosis|prescription|patient',  # 健康
            ],
            DataClassification.CONFIDENTIAL: [
                r'salary|compensation|bonus',
                r'api[_-]?key|password|secret',
                r'confidential|internal only',
            ],
            DataClassification.INTERNAL: [
                r'@company\.com',
                r'internal|draft|not for distribution',
            ]
        }

        for classification, pattern_list in patterns.items():
            if any(re.search(p, data, re.I) for p in pattern_list):
                return classification

        return DataClassification.PUBLIC

    def apply_protection(self, data: str, classification: DataClassification,
                         operation: str) -> str:
        """根據分類套用適當的保護"""
        handlers = {
            DataClassification.RESTRICTED: {
                "include_in_context": self._redact_fully,
                "log": self._redact_fully,
                "output": self._redact_fully,
            },
            DataClassification.CONFIDENTIAL: {
                "include_in_context": self._mask_partially,
                "log": self._redact_fully,
                "output": self._mask_partially,
            },
            DataClassification.INTERNAL: {
                "include_in_context": lambda x: x,
                "log": self._mask_partially,
                "output": lambda x: x,
            },
        }

        handler = handlers.get(classification, {}).get(operation, lambda x: x)
        return handler(data)

    def _redact_fully(self, data: str) -> str:
        return "[REDACTED]"

    def _mask_partially(self, data: str) -> str:
        if len(data) <= 4:
            return "****"
        return data[:2] + "*" * (len(data) - 4) + data[-2:]

應該做與不應該做的事

✅ 應該做

  • 對所有 Agent 工具和權限套用最小權限原則
  • 驗證和清理所有外部輸入(使用者訊息、文件、API 回應)
  • 對高風險操作實施人機協作控制
  • 在使用者/會話之間隔離記憶體和上下文
  • 監控 Agent 行為並設定異常偵測
  • 使用具有 schema 驗證的結構化輸出
  • 簽署和驗證 Agent 間通訊
  • 分類資料並套用適當的保護

❌ 不應該做

  • 給予 Agent 無限制的工具存取或萬用字元權限
  • 信任來自外部來源的內容(網站、電子郵件、文件)
  • 允許 Agent 在沒有沙箱的情況下執行任意程式碼
  • 在 Agent 記憶體中儲存敏感資料而不加密/遮蔽
  • 讓 Agent 在沒有人工監督的情況下做出高影響決策
  • 忽略成本控制(無限迴圈可能導致錢包拒絕服務)
  • 在多 Agent 系統中傳遞未清理的資料
  • 以明文記錄敏感資料(PII、憑證)

安全實施檢查清單

在部署 AI Agent 之前,請確保完成以下檢查項目:

工具安全

  • [ ] 已實施最小權限原則
  • [ ] 所有工具都有允許清單/阻擋清單

輸入驗證

  • [ ] 已實施輸入清理
  • [ ] 已設定注入模式過濾

記憶體安全

  • [ ] 已實施使用者/會話隔離
  • [ ] 已設定記憶體過期和大小限制

人機協作

  • [ ] 高風險操作需要人工批准
  • [ ] 已實施操作預覽功能

輸出驗證

  • [ ] 已實施敏感資料過濾
  • [ ] 已設定速率限制

監控

  • [ ] 已記錄所有 Agent 操作
  • [ ] 已設定異常偵測警報

多 Agent 安全

  • [ ] 已實施 Agent 間信任邊界
  • [ ] 已驗證 Agent 間通訊

資料保護

  • [ ] 已實施資料分類
  • [ ] 敏感資料已加密

參考資源

以下資源可幫助您深入了解 AI Agent 安全:


本文件基於 OWASP AI Agent Security Cheat Sheet 編譯

建議定期檢視並更新安全實踐以應對新興威脅

林子婷 (飛飛/Phoebe 菲比)
林子婷 (飛飛/Phoebe 菲比)

講師學歷:臺科資工所、逢甲資工系畢業。
技術專長:OSINT、滲透測試、網站開發、專業易懂教育訓練。
證照書籍:OSCP、OSCE³、著《資安這條路:領航新手的 Web Security 指南》。
教學經驗:60+ 企業教學經驗、指導過上百位學員。
教學特色:新手友善、耐心指導、擅長圖解(流程圖、心智圖)引導學習。
社群經驗:目前經營全臺資安社群 CURA,曾任臺科資安社社長、逢甲黑客社社長。
社群交流:LINE 社群《飛飛的資安大圈圈》,即時分享經驗、鼓勵交流。
社群分享:FB 粉專《資安這條路,飛飛來領路》,分享文章與圖卡整理。
個人網站:feifei.tw 分享資安技術文章;pbtw.tw 分享 AI 相關應用;ssdlc.feifei.tw 分享軟體安全開發流程文章。