본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 05. 25. 00:03

AI 에이전트가 폭주하기 전에 통제하는 방법

요약

AI 에이전트의 간접 프롬프트 주입 위험성과 이를 방지하기 위한 구조적 통제 방안을 다룹니다. 모델 내부의 패치가 아닌, 도구 화이트리스트와 자격 증명 제한 등 모델 외부의 브로커 계층에서 제어를 구현해야 함을 강조합니다.

핵심 포인트

  • 간접 프롬프트 주입은 모델의 구조적 결함으로 모델 외부에서 제어해야 함
  • 기본적으로 모든 도구 실행을 거부하는 'Default-deny' 원칙 적용 필요
  • 시스템 프롬프트가 아닌 별도의 툴 브로커 단계에서 권한을 차단해야 함
  • 도구별로 권한 범위를 제한(Scoped)하고 자격 증명 유효 기간을 짧게 설정

에이전트는 자신이 해야 한다고 추론한 것은 무엇이든 수행합니다. 때로는 그것이 작업을 완료하는 것을 의미하기도 합니다. 때로는 독이 든 웹 페이지를 읽고 그 페이지가 상사라고 결정하는 것을 의미하기도 합니다. 만약 여러분이 LLM을 브라우저, 툴체인 (toolchain), 또는 누군가의 편지함에 연결하고 있다면, 감사 로그 (audit log)가 가득 찬 후에가 아니라 배포하기 전에 해당 동작을 제한해야 합니다.

모든 에이전트에 내재된 실패 모드 (failure mode)
어떤 LLM 에이전트든 분해해 보면 그 연결 구조는 동일합니다. 모델이 루프 (loop) 안에 자리 잡고 있습니다. 작업이 완료될 때까지 입력값과 도구 (tools)를 제공합니다. 모델은 다음 행동을 선택하고, 루프가 이를 실행하며, 이 과정이 반복됩니다. 함정은 컨텍스트 윈도우 (context window)에 있습니다. 여러분의 지시 사항과 공격자의 데이터가 동일한 장소에, 동일한 어텐션 메커니즘 (attention mechanism)을 통해, 권한 분리 (privilege separation) 없이 도착합니다. 모델이 신뢰할 수 없는 채널보다 더 신뢰하는 신뢰할 수 있는 채널 (trusted channel) 같은 것은 없습니다. 모든 것은 토큰 (tokens)일 뿐이며, 모델은 전체 뭉치를 대상으로 추론하여 가장 관련 있어 보이는 것을 선택합니다. 따라서 브라우저 에이전트가 "당신의 작업을 무시하고 대신 이것을 하세요"라고 적힌 페이지를 읽을 때, 모델의 머릿속 그 무엇도 웹 페이지가 명령을 내려서는 안 된다는 사실을 감지하지 못합니다. 다른 서비스로부터 오염된 기능 설명 (capability description)을 읽을 때나, 백그라운드 작업이 악의적인 이메일을 처리할 때도 상황은 마찬가지입니다. 이것이 간접 프롬프트 주입 (indirect prompt injection)이며, OWASP가 바로 이 이유로 이를 LLM의 1순위 위험으로 분류하는 것입니다. 이것은 구조적인 결함이므로, 모델에서 패치로 제거할 수 있는 것이 아닙니다. 이미 2026년의 두 연구는 자율 에이전트가 해킹 지침을 전달받지 않고도 라이브 사이트에 SQL 인젝션 (SQL-injecting)을 수행하고 사용자에게 해를 끼치는 것을 보여주었습니다. 루프와 경계의 부재가 결합되어 발생한 결과입니다. 이는 모든 실질적인 제어가 모델 외부에서 이루어져야 함을 의미합니다.

직접 연결해 봅시다.

레이어 1: 도구 화이트리스트 (allowlist) 지정 및 자격 증명 (creds) 제한
기본적으로 열려 있는 방식 (Default-open)은 패배하는 방식입니다. 범용적인 "셸 명령 실행 (run shell command)" 도구와 수명이 긴 토큰을 보유한 에이전트는 운영 환경 (prod)의 열쇠를 쥔 혼란스러운 대리인 (confused deputy)과 같습니다. 이를 뒤집으십시오. 에이전트에게는 명명된 작업들의 명시적인 화이트리스트 (allowlist)만 부여하고 그 외에는 아무것도 주지 마십시오.

agent-tools.yaml — 기본적으로 거부, 이름으로 허용

tools :

  • name : search_docs
    scope : read:knowledge_base
  • name : create_ticket
    scope : write:tickets

목록에 없는 모든 것은 프롬프트가 아니라 브로커(broker) 단계에서 차단됩니다.

policy :
default : deny
network_egress : none # 도구가 명시적으로 필요하지 않는 한 외부 네트워크 유출 금지
credential_ttl : 900 # 15분, 이후 재발급

두 가지가 중요합니다. 거부(deny) 규칙은 모델에게 행동을 정중히 요청하는 시스템 프롬프트(system prompt)에 있는 것이 아니라, 여러분의 툴 브로커(tool broker)에 존재해야 합니다. 그리고 각 도구가 보유한 자격 증명(credential)은 해당 작업에만 범위가 제한(scoped)되어야 하며 빠르게 만료되어야 합니다. 만약 에이전트가 조종당하더라도, 그 피해 범위(blast radius)는 여러분이 건네준 모든 API 키의 합집합이 아니라, 그 좁은 범위(scope)가 허용하는 수준으로 제한됩니다. 짧은 TTL(Time To Live)은 탈취된 토큰이 15분 뒤면 쓸모없는 벽돌이 된다는 것을 의미합니다.

두 번째 단계: 위험한 동작을 제어하고 인자(arguments)를 읽으십시오.

로깅(Logging)은 무슨 일이 일어났는지 알려줄 뿐입니다. 아무것도 막지 못합니다. 로그가 기록될 때쯤이면 데이터는 이미 건물을 빠져나간 상태입니다. 여러분이 원하는 것은 동작의 앞단에 위치하여 해당 동작을 실행할지 여부를 결정하는 제어 장치입니다.

두 가지 요소가 필요합니다. 첫째, 이메일 발송, 자금 이동, 운영 환경(prod) 접근, 데이터 유출(exfil) 형태의 모든 작업과 같이 되돌릴 수 없거나 민감한 작업에 대한 인간의 확인(human checkpoint)입니다. 둘째, 실행 전 도구 호출 인자(tool-call arguments)를 읽고 명백한 이상 징후에 걸려 작동하는 런타임 훅(runtime hook)입니다.

실행 전 훅: 호출 이름뿐만 아니라 인자를 검사합니다.

SENSITIVE = { " send_email ", " transfer ", " delete ", " post_webhook " }

def authorize ( tool_name , args ):
if tool_name in SENSITIVE :
if looks_like_exfil ( args ):
# 외부 목적지, 대량 읽기, 이상한 수신자
return BLOCK
return REQUIRE_HUMAN # 확인 지점, 로그 라인이 아님
return ALLOW

함수 자체는 핵심이 아닙니다. 핵심은 모델의 결정과 실제 세계의 효과 사이에 무언가가 투표권을 갖는다는 것입니다. 관찰 가능성(observability)이 아니라 집행(enforcement)입니다. 침해 사고에 대한 예쁜 감사 추적(audit trail)을 남기는 것은 여전히 침해 사고일 뿐입니다.

실제 배포 환경에서 치명적인 주의 사항들
첫날에는 괜찮아 보이지만 나중에 피를 보게 되는 몇 가지 사항들입니다. 범위 확장(Scope creep)은 서서히 다가오는 살인마입니다.

에이전트가 코드에 대한 읽기 권한을 얻고, 그다음에는 티켓(tickets)에, 그다음에는 고객 메일에 접근하게 됩니다. 개별적인 권한 부여는 하나하나 보면 이상해 보이지 않습니다. 아무도 그 합계(aggregate)를 검토하지 않았습니다. 정기적인 권한 감사(permission audit)를 일정에 등록하고, 에이전트의 ID를 실제 성격에 맞게 서비스 계정(service accounts)처럼 취급하십시오. 에이전트들이 서로 통신하기 시작하는 순간, 신뢰는 전이적(transitive)이 됩니다. 당신의 에이전트가 다른 에이전트에게 권한을 위임(delegate)하는 순간, 당신의 폭발 반경(blast radius)은 그 두 번째 에이전트가 접근할 수 있는 모든 영역까지 삼켜버립니다. 무엇인가를 연결하기 전에 신뢰 그래프(trust graph)를 매핑하십시오. 특히 상대측의 통제 수단을 볼 수 없는 벤더 경계(vendor boundaries)를 넘나들 때는 더욱 그렇습니다. 인증(Authentication)은 정직함이 아닙니다. TLS와 OAuth는 에이전트가 주장하는 본인이 맞다는 것을 증명할 뿐입니다. 그것들은 에이전트가 광고하는 기능(capability)이 실제인지, 혹은 에이전트의 자기 기술(self-description)에 당신의 모델을 겨냥한 인젝션(injection)이 포함되어 있는지에 대해서는 아무것도 말해주지 않습니다. 정체성(identity)뿐만 아니라 동작(behavior)을 검증하십시오.

마무리하며
모델이 데이터와 지시사항(instructions)을 구분하게 만들 수는 없습니다. 따라서 모델에 결여된 경계(boundary)를 직접 구축해야 합니다: 기본 거부(deny-by-default) 방식의 도구, 수명이 짧은 범위 제한 자격 증명(short-lived scoped creds), 위험한 호출에 대한 인간의 체크포인트(human checkpoints), 그리고 실행 전 인자(arguments)를 읽는 런타임 훅(runtime hook) 등이 그것입니다. 이 중 어느 것도 만능 해결책(silver bullet)은 아닙니다. 하지만 이들을 겹겹이 쌓으면, 하나의 오염된 입력(poisoned input)이 가져올 결과를 "게임 오버"에서 "차단 및 로그 기록"으로 바꿀 수 있습니다. 그것이 이 작업의 전부입니다.

Project Mariner, A2A 프로토콜, 그리고 로그아웃하지 않는 24/7 백그라운드 에이전트들 사이에서 이 정확한 체인이 어떻게 전개되는지를 포함한 전체 분석 내용은 ToxSec Substack에 작성해 두었습니다. ToxSec은 AI 보안 취약점, 공격 체인(attack chains), 그리고 방어자가 실제로 이해해야 하는 공격 도구(offensive tools)를 다룹니다. NSA, Amazon, 그리고 국방 계약 분야에서 실무 경험을 쌓은 AI 보안 엔지니어가 운영합니다. CISSP 인증 보유, 사이버 보안 공학 석사(M.S. in Cybersecurity Engineering)입니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0