← 모든 글

당신의 에이전트에는 신뢰할 수 없는 입력이 둘 있다

가이드에서: Claude Code Comprehensive Guide

전통적인 프로그램에는 신뢰 경계가 하나 있습니다. 사용자가 건네는 입력입니다. 그 경계에서 검증하면 대체로 끝입니다. 에이전트는 조용히 경계를 둘 더 추가했고, 에이전트 주변에 만들어진 도구 대부분은 그중 하나만 진짜로 취급합니다.

첫 번째 새 입력은 모델이 쓰고 당신의 프로세스가 실행하는 코드입니다. 두 번째는 모델이 읽고 그에 따라 행동하는 도구 출력입니다. 둘 다 당신이 통제하지 않는 곳, 곧 언어 모델의 샘플링 분포나 제3자의 서버에서 당신의 시스템으로 넘어오며, 둘 다 도착하는 순간 신뢰된 것으로 취급됩니다. 지금 에이전트 보안이 불안정하게 느껴지는 이유는, 업계가 첫 번째 입력에 대해서는 믿을 만한 답을 갖고 있으면서 두 번째 입력도 같은 문제인 척하고 있기 때문입니다. 같은 문제가 아닙니다.

핵심 요약

  • 에이전트에는 신뢰할 수 없는 입력이 하나가 아니라 둘 있습니다. 런타임이 실행하는 모델 생성 코드와, 모델이 받아들여 행동하는 도구/서버 출력입니다. 둘은 다른 방식으로 실패하고 다른 방어가 필요합니다. 둘을 뒤섞는 것이 사람들이 샌드박스 안에 있다고 느끼면서도 공격에 노출된 채로 남는 이유입니다.12
  • 신뢰할 수 없는 코드 실행에는 마침내 믿을 만한 격리 답이 생겼습니다. Simon Willison의 micropython-wasm은 모델이 쓴 Python을 메모리와 CPU 제한, 통제된 파일 및 네트워크 접근을 갖춘 WebAssembly 샌드박스 안에서 실행합니다. 진짜 샌드박스에 필요한 특성들을, “거의 10년 동안 브라우저에서 시험된” 기반 위에서 갖춘 것입니다.1
  • 도구 포이즈닝은 코드 실행 문제가 아니므로, 코드 샌드박스는 아무 소용이 없습니다. MCP 도구 설명에 숨겨진 악성 지시는 “사용자에게는 보이지 않지만 AI 모델에게는 보이며”, 오염된 도구가 한 번도 실행되지 않아도 에이전트를 탈취할 수 있습니다.23
  • 가장 깊은 문제는 연결 시점과 런타임 사이의 신뢰 격차입니다. 도구 설명은 승인 시점에 한 번 검토됩니다. 도구 응답은 동등한 검사 없이 모델의 컨텍스트로 곧장 흘러 들어가며, 악성 서버는 당신이 승인한 뒤에 설명을 바꿀 수 있습니다.2

두 입력, 두 실패 방식

두 입력을 나란히 놓고 보십시오. 비대칭이 요점의 전부이기 때문입니다.

모델이 코드를 쓰고 당신이 그것을 exec()할 때, 실패 방식은 코드가 당신의 머신에 무언가를 한다는 것입니다. 읽으면 안 되는 파일을 읽고, 소켓을 열고, CPU를 영원히 돌리고, 상태를 망가뜨립니다. 폭발 반경은 당신의 프로세스와 그것이 닿을 수 있는 모든 것입니다. 방어는 오래되었고 잘 이해되어 있습니다. 격리입니다. 중요한 것에 손댈 수 없는 곳에서 코드를 실행하는 것입니다.

모델이 도구 출력을 읽고 그에 따라 행동할 때, 실패 방식은 그 말이 모델이 하기로 결정하는 것을 바꾼다는 것입니다. 고전적인 의미에서 당신의 호스트에서 실행되는 것은 아무것도 없습니다. 대신 “데이터”로 도착한 텍스트가 “지시”로 해석되고, 당신의 자격 증명을 쥔 에이전트가 그것을 수행합니다. 폭발 반경은 당신의 에이전트가 하도록 허가된 모든 것입니다. 프로세스 격리는 아무리 해도 도움이 되지 않습니다. 에이전트는 애초에 그 도구를 읽고 그에 따라 행동할 수 있어야 했기 때문입니다. 공격은 정당한 경로를 타고 옵니다.

코드 샌드박스는 첫 번째 입력을 둘러싼 벽입니다. 필요한 것이고, 마침내 좋아지고 있습니다. 그리고 두 번째 입력에 대해서는 완전히 침묵합니다.

마침내 샌드박스를 갖게 된 입력

2026년 6월 6일, Simon Willison은 micropython-wasm을 공개했습니다. WebAssembly 샌드박스에서 Python을 실행하는 알파 패키지로, 여러 해 동안 딱 맞지 않는 접근법들을 시도한 끝에 나온 것입니다.1 동기는 정확히 첫 번째 신뢰할 수 없는 입력입니다. 그는 자신의 Datasette Agent 안에서 LLM이 생성한 코드를 호스트를 위험에 빠뜨리지 않고 실행하고 싶어 하며, 그의 표현대로 “버그가 있거나 악의적인 플러그인은 모든 것을 망가뜨리거나 개인 데이터를 유출할 수 있습니다.”1

주목할 가치가 있는 이유는 이것이 실제로 충족하는 체크리스트 때문입니다. 그 체크리스트가 곧 쓸 만한 샌드박스의 정의이기 때문입니다.

  • 메모리와 CPU 제한. 모델이 쓴 while True: s += "x"가 호스트를 고갈시킬 수 없습니다. CPU는 wasmtime의 “fuel” 메커니즘으로 제한되는데, Willison은 그 단위가 “추론하기 어렵다”고 솔직하게 밝힙니다.1
  • 통제된 파일 및 네트워크 접근. 기본 열림이 아니라 기본 거부입니다.
  • 깨끗한 격리 모델. 코드는 요청/응답 큐 뒤의 별도 스레드에서 실행되고, WASM 인터프리터는 작업을 건네받을 때까지 호스트 함수에서 블로킹됩니다. 그래서 신뢰할 수 없는 코드는 호스트의 주소 공간을 결코 공유하지 않습니다.1
  • 실적이 있는 기반. 그가 WebAssembly를 택한 이유는 그것이 “처음부터 내가 중시하는 모든 특성을 지원하도록 설계되었고 거의 10년 동안 브라우저에서 시험되었기” 때문이며, MicroPython을 택한 이유는 브라우저 지향의 Pyodide가 서버 측에서 지원되지 않기 때문입니다.1

그 솔직함이 좋은 보안 작업의 표식입니다. Willison은 이것을 알파로 내놓으며 “상당한 위험을 감수할 의사가 없는 사람에게는 추천할 준비가 되어 있지 않다”고 씁니다.1 그것이 증거 게이트의 자세입니다. 검증한 것만 정확히 주장하고 그 이상은 주장하지 않는 것입니다. 요점은 이 패키지 하나가 답이라는 것이 아닙니다. 신뢰할 수 없는 코드에 대한 답의 형태가 이제 분명하고 재현 가능하다는 것입니다. 자원 제한과 기본 거부 I/O를 갖춘 진짜 격리 경계입니다. 첫 번째 입력은 해결된 엔지니어링 문제가 되어 가고 있습니다.

함정은 그것을 해결하면 안전해진다고 믿는 것입니다.

샌드박스가 없는 입력

두 번째 입력은 코드를 실행하지 않으므로, 벽은 아무것도 하지 못합니다. 2025년 4월 1일, Invariant Labs는 도구 포이즈닝 공격을 공개했습니다. “악성 지시가 MCP 도구 설명 안에 삽입되어 사용자에게는 보이지 않지만 AI 모델에게는 보입니다.”2 비대칭이 곧 공격입니다. “AI 모델은 숨겨진 지시를 포함한 완전한 도구 설명을 보는 반면, 사용자는 보통 UI에서 단순화된 버전만 봅니다.”2 UI에서는 “두 수를 더합니다”라고 읽히는 도구가, 모델이 실제로 소비하는 설명에서는 ~/.ssh/id_rsa를 읽어 숨겨진 매개변수를 통해 유출하라는 지시를 담고 있을 수 있습니다.2 OWASP는 이제 이것을 이름 붙은 공격 유형으로 분류합니다.3

격리가 닿을 수 없는 방식으로 이것을 고약하게 만드는 두 가지 속성이 있습니다.

도구가 호출되지 않아도 발동합니다. 오염된 지시는 설명 안에 살고, 모델은 도구 집합을 검토할 때 그것을 받아들입니다. 그래서 함수가 한 번도 실행되지 않아도 공격이 성공할 수 있습니다.3 샌드박스에 넣을 코드 이벤트가 없습니다.

신뢰는 한 번 부여되고 나중에 악용됩니다. 도구 설명은 서버를 승인하는 연결 시점에 검토됩니다. 그 뒤 응답은 런타임에 동등한 검사 없이 모델의 컨텍스트로 곧장 흘러 들어갑니다. 그리고 Invariant의 “러그 풀” 발견에 따르면, “악성 서버는 클라이언트가 이미 승인한 뒤에 도구 설명을 바꿀 수 있습니다.”2 당신의 일회성 승인은 지속되는 어떤 것도 지켜 주지 않습니다.

대표적인 시연은 가상이 아닙니다. 연구자들은 GitHub 이슈에 주입 텍스트를 심었습니다. 개발자가 어시스턴트에게 열린 이슈를 검토하라고 하자, 에이전트는 이슈를 받아들이고, 숨겨진 지시를 따르고, 개발자의 토큰으로 비공개 저장소를 읽고, 그 내용을 공개 풀 리퀘스트에 유출했습니다.3 각각의 개별 행동은 허가된 것이었습니다. 에이전트는 정확히 에이전트가 하라고 만들어진 일을 했습니다. 그래서 여기서는 코드 샌드박스가 무관합니다. 신뢰할 수 없는 것이 실행된 것이 아니라, 신뢰할 수 없는 텍스트가 진짜 자격 증명을 쥔 프로세스 안에서 지시로 승격된 것뿐입니다. Ken Thompson이 Reflections on Trusting Trust에 남긴 것과 같은 교훈입니다. 위험은 당신이 검사하는 코드가 아니라, 검사하지 않고 확장하는 신뢰에 있습니다.

두 번째 입력 방어하기

격리가 코드에 대한 방어라면, 도구 출력에 대한 방어는 데이터와 지시 사이의 경계를 런타임에, 매번, 실재하는 것으로 취급하는 것입니다. 연결 시점 승인 모델이 건너뛰는 바로 그것입니다. Microsoft 자체의 MCP 지침도 같은 곳에 도달합니다. 주입된 지시를 탐지하고 걸러 내는 “프롬프트 실드”와, “시스템 메시지에 구분자를 포함해 입력 텍스트의 위치를 명시적으로 표시하는” 스포트라이팅을 권고해, 모델이 내용과 명령을 구별할 수 있게 하는 것입니다.4 구체적으로는:

  • 승인 시점만이 아니라 런타임에 설명을 다시 확인합니다. 승인한 도구 정의를 고정하고, 서버의 설명이 발밑에서 바뀌면 탐지합니다. 러그 풀이 통하는 이유는 아무도 두 번 보지 않기 때문입니다.2
  • 데이터/지시 경계를 명시적으로 표시합니다. 도구 응답은 지시가 아니라 데이터입니다. 실용적인 버전이 스포트라이팅입니다. 컨텍스트 안에서 도구 출력을 구분자로 감싸, 그것이 따라야 할 명령이 아니라 추론 대상인 내용이라고 모델에게 구조적으로 알려 주는 것입니다.4 이것은 MCP 도구의 행동 수준 권한 부여와 짝을 이루어, 탈취된 에이전트라도 결과가 중대한 호출에는 닿지 못하게 합니다.
  • 허가된 경로에 최소 권한을 적용합니다. GitHub 공격이 통한 이유는 한 에이전트가 “비공개 저장소 읽기”와 “공개 PR 열기”를 둘 다 쥐고 있었기 때문입니다. 그리고 최소 권한은 Microsoft가 이런 공격에 대한 기본 위생으로 정확히 지목하는 것입니다.4 Joanna Rutkowska의 구획화를 통한 보안은 아키텍처 수준에서 같은 본능입니다. 한 도메인이 침해되었다고 가정하고, 그것이 다른 도메인에 닿지 못하게 하는 것입니다. 이슈를 읽는 에이전트가 유출 경로를 쥔 에이전트여서는 안 됩니다.
  • 이그레스를 감시합니다. 유출이 목적이기 때문입니다. 이런 공격 대부분은 같은 단계, 곧 데이터가 나가는 단계에서 끝납니다. 조용한 이그레스 관점은 주입이 정문을 통과하더라도 그 결과를 잡아냅니다.

이 가운데 어느 것도 벽이 아닙니다. 에이전트가 걸어가도록 만들어진 경로 위의 문입니다. 더 어렵고 덜 만족스러운 종류의 보안이며, 두 번째 입력이 실제로 요구하는 종류입니다.

내가 여기서 얻는 것

내가 간직하는 심적 모델은, “내 에이전트는 샌드박스 안에 있는가?”가 잘못된 질문이라는 것입니다. 지켜야 할 경계가 하나라고 조용히 가정하기 때문입니다. 경계는 둘입니다. 내 모델이 쓰는 코드에는 벽이 필요합니다. Willison 같은 이들의 작업 덕분에, 그 벽을 세우는 것은 분명한 명세를 가진 평범한 엔지니어링 작업이 되어 가고 있습니다. 내 모델이 읽는 도구 출력에는 완전히 다른 것이 필요합니다. 데이터가 조용히 지시가 되도록 결코 두지 않는 런타임과, 탈취된 에이전트가 그래도 할 수 있는 것이 별로 없을 만큼 촘촘한 권한 부여 모델입니다. 둘을 뒤섞는 것은, “봐, 코드는 WASM에서 돌아”라며 보호받고 있다고 느끼면서도 아무도 문을 달지 않은 입력을 통해 활짝 열린 채로 남는 방법입니다.

더 깊은 연속성은, 에이전트가 새로운 범주의 취약점을 발명했다기보다 오래된 취약점이 살 새로운 자리를 추가했다는 것입니다. 신뢰할 수 없는 입력은 언제나 보안의 뿌리였습니다. 에이전트 시대는 거기에 새 문을 둘 달았을 뿐입니다. 하나는 격리로 잠글 수 있고, 다른 하나는 규율로 지켜볼 수 있을 뿐입니다. 벽과 문을 함께 세우십시오. 입력이 둘인 시스템에서 벽만 세우는 것은, 온전한 방어처럼 느껴지는 절반의 방어입니다.

자주 묻는 질문

AI 에이전트의 두 가지 신뢰할 수 없는 입력은 무엇입니까?

런타임이 실행하는 모델 생성 코드와, 모델이 읽고 그에 따라 행동하는 도구 또는 서버 출력입니다. 첫 번째는 호스트를 직접 손상시킬 수 있고, 두 번째는 에이전트가 이미 쥐고 있는 자격 증명과 권한을 이용해 에이전트의 결정을 탈취할 수 있습니다. 둘은 다른 방어가 필요합니다. 코드에는 격리, 도구 출력에는 런타임의 데이터/지시 분리와 촘촘한 권한 부여입니다.12

코드 샌드박스가 MCP 도구 포이즈닝을 막아 줍니까?

아닙니다. 도구 포이즈닝은 당신의 호스트에서 코드를 실행하지 않습니다. 모델이 신뢰된 것으로 취급하는 도구 설명 안에 지시를 심으며, 도구가 한 번도 호출되지 않아도 발동할 수 있습니다.23 샌드박스는 실행을 격리하므로, 에이전트의 정당하고 허가된 행동을 타고 오는 공격에는 아무 소용이 없습니다.

도구 포이즈닝 공격이란 무엇입니까?

2025년 4월 Invariant Labs가 공개한 공격으로, “악성 지시가 MCP 도구 설명 안에 삽입되어 사용자에게는 보이지 않지만 AI 모델에게는 보이는” 공격입니다.2 모델은 전체 설명을 보고 사용자는 단순화된 UI 레이블만 보기 때문에, 예를 들어 SSH 키를 읽어 유출하라는 숨겨진 지시가 에이전트를 탈취할 수 있습니다. OWASP는 이제 이것을 이름 붙은 공격 유형으로 추적합니다.23

연결 시점 대 런타임 신뢰 격차란 무엇입니까?

도구 설명은 서버를 승인할 때(연결 시점) 한 번 검토됩니다. 그 뒤 도구 응답은 런타임에 동등한 검사 없이 모델의 컨텍스트로 흘러 들어가며, 악성 서버는 승인 뒤에 설명을 바꿀 수 있습니다(“러그 풀”).2 해결책은 승인 시점만이 아니라 런타임에 검증하는 것입니다.


출처


  1. Simon Willison, “Running Python code in a sandbox with MicroPython and WASM,” simonwillison.net, 2026년 6월 6일. 알파 micropython-wasm 패키지와 datasette-agent-micropython 플러그인 소개; “버그가 있거나 악의적인 플러그인은 모든 것을 망가뜨리거나 개인 데이터를 유출할 수 있다”는 동기; 샌드박스 체크리스트(wasmtime “fuel”을 통한 메모리/CPU 제한, 통제된 파일/네트워크 접근, 별도 스레드의 요청/응답 격리); WebAssembly가 “처음부터 내가 중시하는 모든 특성을 지원하도록 설계되었고 거의 10년 동안 브라우저에서 시험되었다”는 근거; 그리고 “상당한 위험을 감수할 의사가 없는 사람에게는 추천할 준비가 되어 있지 않다”는 단서. ↩↩↩↩↩↩↩↩↩

  2. Luca Beurer-Kellner and Marc Fischer, “MCP Security Notification: Tool Poisoning Attacks,” Invariant Labs, 2025년 4월 1일. 최초 공개: “도구 포이즈닝 공격은 악성 지시가 MCP 도구 설명 안에 삽입되어 사용자에게는 보이지 않지만 AI 모델에게는 보일 때 발생한다”; 가시성 격차(“AI 모델은 숨겨진 지시를 포함한 완전한 도구 설명을 보는 반면, 사용자는 보통 UI에서 단순화된 버전만 본다”); “악성 서버는 클라이언트가 이미 승인한 뒤에 도구 설명을 바꿀 수 있다”는 “러그 풀” 발견; 그리고 ~/.cursor/mcp.json과 ~/.ssh/id_rsa를 읽는 오염된 add 예시. ↩↩↩↩↩↩↩↩↩↩↩↩↩

  3. “MCP Tool Poisoning,” OWASP Foundation. 도구 포이즈닝을 이름 붙은 공격 유형으로 분류: “오염된 도구가 한 번도 호출되지 않아도” 에이전트에 영향을 주는 도구 메타데이터 속 숨겨진 지시, 그리고 오염된 이슈가 에이전트로 하여금 개발자의 토큰으로 비공개 저장소를 읽어 공개 풀 리퀘스트에 유출하게 만드는 GitHub MCP 예시. ↩↩↩↩↩↩

  4. Sarah Young and Den Delimarsky, “Protecting against indirect prompt injection attacks in MCP,” Microsoft Developer Blog, 2025년 4월 28일. “고급 기계 학습 알고리즘과 자연어 처리를 사용해 악성 지시를 탐지하고 걸러 내는” “프롬프트 실드”, “시스템 메시지에 구분자를 포함해 입력 텍스트의 위치를 명시적으로 표시하는” 스포트라이팅, MCP 구성 요소의 공급망 검증, 그리고 최소 권한 같은 기본 위생을 권고. ↩↩↩

관련 게시물

에이전트 샌드박스는 제안일 뿐입니다

한 공격자가 GitHub 이슈를 열고 Cline의 다음 릴리스에 악성코드를 심었습니다. 에이전트 샌드박스는 세 가지 수준에서 실패합니다. 실제로 효과가 있는 방법을 소개합니다.

16 분 소요

MCP 서버가 새로운 공격 표면입니다

50개의 MCP 취약점, 60일 만에 30개의 CVE, 13개의 치명적 취약점. 도구 사용 프로토콜은 아무도 감사하지 않는 공격 표면입니다 — 분류 체계와 해결책을 제시합니다.

7 분 소요

Ralph 루프: 자율 AI 에이전트를 밤새 운영하는 방법

중지 훅, 스폰 예산, 파일 시스템 메모리를 활용한 자율 에이전트 시스템을 구축했습니다. 실패 사례와 실제로 코드를 출시하게 된 과정을 공유합니다.

10 분 소요