에이전트 애플리케이션을 위한 OWASP 톱 10은 무엇인가요?

자율적으로 계획하고, 도구를 사용하고, 외부 서비스와 상호 작용하는 AI 에이전트 시스템과 관련된 가장 중요한 보안 위험의 순위입니다. 2026년 버전에서는 에이전트 AI가 연구용에서 프로덕션 배포로 이동하면서 새롭게 등장하는 위협을 다룹니다.

1️⃣ ASI01 - 상담원 목표 하이재킹

Critical

개요

공격자는 조작된 입력을 통해 에이전트의 목표 또는 목적을 조작하여 의도하지 않은 목표를 추구하도록 합니다. 단순한 프롬프트 인젝션과 달리 목표 하이재킹은 여러 계획 단계에서 지속될 수 있으며, 에이전트가 일련의 유해한 작업을 자율적으로 수행하도록 만들 수 있습니다.

위험

공격자는 자율 에이전트를 리디렉션하여 데이터를 유출하거나 시스템 구성을 수정하거나 에이전트가 정상적으로 작동하는 것처럼 보이기 때문에 탐지하기 어려운 다단계 공격 체인을 수행할 수 있습니다.

취약한 코드 예시

Python ❌ Bad
# Agent goal is derived directly from untrusted input
def run_agent(user_request: str) -> str:
    goal = f"Complete this task: {user_request}"
    plan = llm.plan(goal)
    for step in plan:
        execute(step)  # No validation of planned steps

보안 코드 예시

Python ✅ Good
import re

ALLOWED_GOALS = ["summarize", "search", "draft_email", "analyze_data"]

def sanitize_goal(user_request: str) -> str:
    # Strip injection patterns
    cleaned = re.sub(r'(?i)(ignore|override|new goal|forget).*', '', user_request)
    return cleaned.strip()

def run_agent(user_request: str) -> str:
    sanitized = sanitize_goal(user_request)
    goal = f"Complete this task: {sanitized}"
    plan = llm.plan(goal)

    # Validate each step against allowed actions
    for step in plan:
        if step.action not in ALLOWED_GOALS:
            raise ValueError(f"Disallowed action: {step.action}")
        if goal_drift_detected(step, sanitized):
            raise ValueError("Goal drift detected, aborting")
    for step in plan:
        execute(step)

완화 체크리스트

2️⃣ ASI02 - 도구 오용 및 악용

Critical

개요

외부 도구(API, 파일 시스템, 데이터베이스, 웹 브라우저)에 액세스할 수 있는 에이전트는 이러한 도구를 오용하도록 조작될 수 있습니다. 제한되지 않은 도구 액세스는 공격자가 에이전트를 통해 무단 작업을 수행할 수 있도록 허용합니다.

위험

도구 액세스 권한이 무제한인 에이전트는 파일을 삭제하거나, 무단 API 요청을 보내거나, 웹 브라우징을 통해 데이터를 유출하거나, 중요한 시스템 구성을 수정할 수 있습니다.

취약한 코드 예시

Python ❌ Bad
# Agent can call any tool without restrictions
def agent_execute(tool_name: str, params: dict):
    tool = tools_registry.get(tool_name)
    return tool(**params)  # No validation or approval

보안 코드 예시

Python ✅ Good
TOOL_ALLOWLIST = {
    "web_search": {"max_calls": 10, "approval": False},
    "send_email": {"max_calls": 1, "approval": True},
    "file_write": {"max_calls": 5, "approval": True},
}

def agent_execute(tool_name: str, params: dict, session) -> str:
    if tool_name not in TOOL_ALLOWLIST:
        return "Error: Tool not permitted"

    config = TOOL_ALLOWLIST[tool_name]
    if session.tool_calls[tool_name] >= config["max_calls"]:
        return "Error: Tool call limit exceeded"

    if config["approval"]:
        if not request_human_approval(tool_name, params):
            return "Action denied by user"

    session.tool_calls[tool_name] += 1
    return tools_registry[tool_name](**params)

완화 체크리스트

3️⃣ ASI03 - 신원 및 권한 남용

Critical

개요

에이전트는 종종 자신을 실행한 사용자 또는 서비스 계정의 ID와 권한을 상속받습니다. 이러한 과도한 권한 상속으로 인해 에이전트가 필요한 것 이상의 작업을 수행할 수 있으며, 에이전트가 손상될 경우 광범위한 공격 표면이 만들어집니다.

위험

관리자 자격 증명으로 실행되는 손상된 에이전트는 모든 시스템에 액세스하고 권한을 수정하며 조직 전체에서 권한을 에스컬레이션할 수 있습니다.

취약한 코드 예시

Python ❌ Bad
# Agent inherits full user credentials
def create_agent(user_session):
    agent = Agent(
        credentials=user_session.full_credentials,  # All permissions!
        scope="*",
    )
    return agent

보안 코드 예시

Python ✅ Good
def create_agent(user_session, task_type: str):
    # Issue scoped, short-lived credentials for the agent
    scoped_token = auth.create_scoped_token(
        parent_token=user_session.token,
        scopes=TASK_SCOPES[task_type],  # Minimal required permissions
        ttl_minutes=30,
        max_actions=50,
    )

    agent = Agent(
        credentials=scoped_token,
        scope=TASK_SCOPES[task_type],
        audit_log=True,
    )
    return agent

TASK_SCOPES = {
    "summarize": ["read:documents"],
    "draft_email": ["read:contacts", "draft:email"],
    "analyze": ["read:data", "write:reports"],
}

완화 체크리스트

4️⃣ ASI04 - 에이전트 공급망 취약성

High

개요

상담원 시스템은 타사 플러그인, 툴 통합 및 공유 상담원 프레임워크에 의존합니다. 에이전트 공급망에서 손상되었거나 악의적인 구성 요소는 백도어, 데이터 유출 채널 또는 무단 기능을 도입할 수 있습니다.

Python ❌ Bad
# Loading plugins without verification
def load_plugin(plugin_url: str):
    code = requests.get(plugin_url).text
    exec(code)  # Arbitrary code execution!
Python ✅ Good
import hashlib, importlib

TRUSTED_PLUGINS = {
    "search_plugin": "sha256:a1b2c3...",
    "email_plugin": "sha256:d4e5f6...",
}

def load_plugin(plugin_name: str) -> None:
    if plugin_name not in TRUSTED_PLUGINS:
        raise ValueError(f"Untrusted plugin: {plugin_name}")

    module = importlib.import_module(f"plugins.{plugin_name}")
    actual_hash = compute_hash(module.__file__)

    if actual_hash != TRUSTED_PLUGINS[plugin_name]:
        raise ValueError("Plugin integrity check failed")

    module.init(sandbox=True)

완화 체크리스트

5️⃣ ASI05 - 예기치 않은 코드 실행

Critical

개요

코드를 생성하고 실행할 수 있는 에이전트(예: 데이터 분석 에이전트, 코딩 어시스턴트)가 속아서 악성 코드를 실행할 수 있습니다. 적절한 샌드박싱이 없으면 시스템 손상, 데이터 도난 또는 측면 이동으로 이어질 수 있습니다.

위험

생성된 코드에서 eval() 또는 exec()를 사용하는 에이전트는 원격 코드 실행에 악용되어 공격자가 전체 시스템 액세스 권한을 획득할 수 있습니다.

취약한 코드 예시

Python ❌ Bad
# Agent executes generated code directly
def code_agent(task: str) -> str:
    code = llm.generate_code(task)
    result = eval(code)  # Dangerous!
    return str(result)

보안 코드 예시

Python ✅ Good
import subprocess, tempfile, os

BLOCKED_MODULES = ["os", "subprocess", "socket", "shutil"]

def code_agent(task: str) -> str:
    code = llm.generate_code(task)

    # Static analysis: block dangerous imports
    for mod in BLOCKED_MODULES:
        if f"import {mod}" in code or f"from {mod}" in code:
            raise ValueError(f"Blocked import: {mod}")

    # Execute in sandboxed container with resource limits
    result = sandbox.run(
        code=code,
        timeout=30,
        memory_mb=256,
        network=False,
        read_only_fs=True,
    )
    return result.output

완화 체크리스트

6️⃣ ASI06 - 메모리 및 컨텍스트 중독

High

개요

영구 메모리(RAG, 대화 기록, 학습된 기본 설정)를 유지하는 상담원은 메모리 중독에 취약합니다. 공격자는 에이전트의 지식창고에 악성 콘텐츠를 삽입하여 향후 상호작용에서 손상된 결과를 생성하도록 합니다.

Python ❌ Bad
# Agent stores all interactions without validation
def store_memory(agent_id: str, interaction: str):
    memory_db.insert(agent_id, interaction)  # No filtering
Python ✅ Good
def store_memory(agent_id: str, interaction: str, source: str):
    # Validate content before storing
    if contains_injection_patterns(interaction):
        log.warning(f"Blocked poisoned memory: {agent_id}")
        return

    memory_db.insert(
        agent_id=agent_id,
        content=interaction,
        source=source,
        provenance=compute_provenance(source),
        timestamp=now(),
        ttl_days=30,  # Auto-expire old memories
    )

def retrieve_memory(agent_id: str, query: str) -> list:
    results = memory_db.search(agent_id, query)
    # Filter by provenance score
    return [r for r in results if r.provenance_score > 0.8]

완화 체크리스트

7️⃣ ASI07 - 안전하지 않은 에이전트 간 통신

High

개요

상담원들이 서로 통신하는 멀티 에이전트 시스템은 메시지 변조, 스푸핑 및 도청에 취약합니다. 적절한 인증 및 무결성 검사가 이루어지지 않으면 손상된 에이전트가 악성 지침을 에이전트 네트워크에 주입할 수 있습니다.

Python ❌ Bad
# Agents communicate via plain text messages
def send_to_agent(target: str, message: str):
    channel.send(target, message)  # No auth, no signing
Python ✅ Good
import hmac, json, time

def send_to_agent(target: str, message: str, sender_key: bytes):
    payload = {
        "content": message,
        "sender": agent_id,
        "target": target,
        "timestamp": time.time(),
        "nonce": os.urandom(16).hex(),
    }
    signature = hmac.new(
        sender_key, json.dumps(payload).encode(), "sha256"
    ).hexdigest()
    payload["signature"] = signature

    encrypted = encrypt(json.dumps(payload), target_public_key)
    channel.send(target, encrypted)

def receive_message(data: bytes, private_key) -> dict:
    payload = json.loads(decrypt(data, private_key))
    if not verify_signature(payload):
        raise ValueError("Invalid message signature")
    if is_replay(payload["nonce"]):
        raise ValueError("Replay attack detected")
    return payload

완화 체크리스트

8️⃣ ASI08 - 계단식 실패

High

개요

다중 에이전트 또는 다단계 워크플로에서는 한 에이전트의 오류나 악의적인 작업이 시스템 전체에 전파되어 연쇄적인 장애를 일으킬 수 있습니다. 적절한 오류 경계가 없으면 손상된 단일 단계로 인해 전체 파이프라인이 손상될 수 있습니다.

Python ❌ Bad
# Errors propagate without boundaries
def pipeline(data):
    result1 = agent_a.process(data)
    result2 = agent_b.process(result1)  # If agent_a fails or is poisoned...
    result3 = agent_c.process(result2)  # ...error cascades to all
    return result3
Python ✅ Good
from circuitbreaker import circuit

class AgentPipeline:
    def __init__(self):
        self.circuit_breakers = {}

    @circuit(failure_threshold=3, recovery_timeout=60)
    def safe_execute(self, agent, data):
        result = agent.process(data)
        if not validate_output(result):
            raise ValueError("Output validation failed")
        return result

    def pipeline(self, data):
        try:
            r1 = self.safe_execute(agent_a, data)
        except Exception:
            r1 = fallback_a(data)

        try:
            r2 = self.safe_execute(agent_b, r1)
        except Exception:
            r2 = fallback_b(r1)

        return r2

완화 체크리스트

9️⃣ ASI09 - 인간-에이전트 신뢰 익스플로잇

Medium

개요

사용자는 상담원의 결과물을 지나치게 신뢰하여 충분한 검토 없이 작업을 승인할 수 있습니다. 신뢰도는 높지만 근거가 불충분한 권장 사항을 제시하는 에이전트는 사용자가 유해한 결정을 내리도록 유도할 수 있습니다. 공격자는 이러한 신뢰 관계를 악용할 수 있습니다.

Python ❌ Bad
# Agent requests approval without context
def request_action(action: str):
    # "Deploy to production?" - user clicks Yes without review
    return ui.confirm(f"Execute: {action}?")
Python ✅ Good
def request_action(action: str, context: dict) -> bool:
    confidence = context.get("confidence", 0.0)
    risk_level = assess_risk(action)

    approval_request = {
        "action": action,
        "confidence": f"{confidence:.0%}",
        "risk_level": risk_level,
        "reasoning": context["reasoning"],
        "affected_systems": context["systems"],
        "reversible": context.get("reversible", False),
    }

    # Force detailed review for high-risk or low-confidence
    if risk_level == "high" or confidence < 0.8:
        return ui.detailed_review(approval_request)

    return ui.confirm(approval_request)

완화 체크리스트

🔟 ASI10 - 로그 에이전트

High

개요

에이전트는 목표 오정렬, 적대적 조작 또는 돌발 행동으로 인해 의도된 목적에서 벗어날 수 있습니다. 불량 에이전트는 조직의 목표와 상충되는 목표를 추구하거나, 자원을 축적하거나, 종료 시도에 저항할 수 있습니다.

Python ❌ Bad
# Agent runs without monitoring or kill switch
def run_agent(task):
    while True:
        agent.step()  # No termination condition
Python ✅ Good
class MonitoredAgent:
    def __init__(self, agent, max_steps=100):
        self.agent = agent
        self.max_steps = max_steps
        self.step_count = 0
        self.behavior_log = []

    def run(self):
        while self.step_count < self.max_steps:
            action = self.agent.next_action()

            # Check for rogue behavior
            if self.is_off_task(action):
                log.alert(f"Rogue behavior: {action}")
                self.shutdown()
                return

            # Check guardrails
            if not guardrails.check(action):
                log.warning(f"Guardrail violation: {action}")
                continue

            self.agent.execute(action)
            self.step_count += 1
            self.behavior_log.append(action)

    def shutdown(self):
        self.agent.stop()
        revoke_credentials(self.agent.id)
        notify_admin(self.behavior_log)

완화 체크리스트

📊 요약 표

ID 취약성 심각도 주요 완화
ASI01에이전트 목표 하이재킹Critical입력 위생 처리, 목표 드리프트 감지, 목표 허용 목록
ASI02도구 오용 및 악용Critical도구 허용 목록, 사람 승인, 속도 제한
ASI03신원 및 권한 남용Critical범위가 지정된 자격 증명, 수명이 짧은 토큰, 최소 권한
ASI04에이전트 공급망 취약성High플러그인 서명 확인, 샌드박스 실행
ASI05예기치 않은 코드 실행Critical샌드박스 컨테이너, 정적 분석, eval() 없음
ASI06메모리 및 컨텍스트 중독High입력 유효성 검사, 출처 추적, 메모리 TTL
ASI07안전하지 않은 에이전트 간 통신High메시지 서명, 암호화, 재생 방지
ASI08계단식 실패High회로 차단기, 출력 유효성 검사, 폴백 핸들러
ASI09인간-에이전트 신뢰 악용Medium신뢰 표시, 상세 검토, 점진적 신뢰
ASI10로그 에이전트High행동 모니터링, 가드레일, 킬 스위치