
MCP 혼동된 대리인(Confused Deputy): 프로토콜 설계의 출처(Provenance) 부재로 인한 인젝션 가능성
요약
Anthropic의 Model Context Protocol(MCP)에서 도구 결과의 암호학적 출처(Provenance) 부재로 인해 발생하는 '혼동된 대리인(Confused Deputy)' 취약점을 분석합니다. 공격자가 제어하는 Markdown 콘텐츠가 모델의 컨텍스트에 주입되어 승인되지 않은 행동을 유도할 수 있는 위험을 경고합니다.
핵심 포인트
- MCP 도구 결과에 암호학적 출처가 없어 인젝션 공격에 취약함
- 공식 fetch 서버가 신뢰 라벨 없이 외부 Markdown을 컨텍스트로 반환함
- DNS 리바인딩을 통한 URL 허용 목록 우회 가능성 존재
- ToolAnnotations는 보안 경계가 아닌 단순 권고 사항임
MCP는 혼동된 대리인(Confused Deputy) 취약점을 가지고 있습니다: 도구 결과에 출처(Provenance)가 없어 인젝션(Injection)을 허용합니다. 공식 fetch 서버는 공격자가 제어하는 Markdown을 컨텍스트(Context)에 전달합니다.
Anthropic의 Model Context Protocol (MCP)는 도구 결과에 대한 암호학적 출처(Cryptographic Provenance)가 부족하여, 혼동된 대리인(Confused Deputy) 취약점을 생성합니다. 공식 fetch 서버는 신뢰할 수 없다는 라벨을 붙이지 않고 공격자가 제어하는 Markdown을 모델의 컨텍스트 창(Context Window)으로 직접 반환합니다.
주요 사실
- MCP 도구 결과에는 암호학적 출처(Cryptographic Provenance)가 부족합니다.
- 공식 fetch 서버는 신뢰 라벨 없이 Markdown을 반환합니다.
- DNS 리바인딩(DNS Rebinding)은 TTL 0을 통해 URL 허용 목록(Allowlist)을 우회합니다.
- ToolAnnotations는 권고 사항일 뿐, 보안 경계(Security Boundary)가 아닙니다.
- 공격에는 단지 fetch 가능한 URL에서 콘텐츠를 제공하는 것만 필요합니다.
Model Context Protocol (MCP)는 LLM과 외부 시스템(파일 시스템, 데이터베이스, API, 브라우저, 내부 도구 등) 사이를 연결하는 결합 조직입니다. 잘 작동하는 에이전트 기반 배포(Agentic Deployment)에서 MCP는 모델이 문서를 읽고, 데이터베이스를 쿼리하며, 세상에서 행동을 취할 수 있게 합니다. 적대적인 배포(Adversarial Deployment) 환경에서 MCP는 공격자가 제어하는 콘텐츠가 모델의 컨텍스트 창에 도달하여, 사용자가 승인하지 않은 행동을 하도록 모델을 설득하는 메커니즘이 됩니다. The MCP Confused Deputy에 따르면
핵심 요약
- MCP는 혼동된 대리인(Confused Deputy) 취약점을 가지고 있습니다: 도구 결과에 출처(Provenance)가 없어 인젝션(Injection)을 허용합니다.
- 공식 fetch 서버는 공격자가 제어하는 Markdown을 컨텍스트(Context)에 전달합니다.
구조적 출처 격차 (The Structural Provenance Gap)

혼동된 대리인(Confused Deputy)은 고전적인 접근 제어(Access-control) 개념입니다. 즉, 정당한 권한을 가진 엔티티가 신뢰할 수 없는 당사자에 의해 조작되어, 해당 신뢰할 수 없는 당사자를 대신하여 그 권한을 행사하게 되는 상황을 의미합니다. MCP에서 혼동된 대리인은 모델 그 자체입니다.
여기에 구조적인 문제가 있습니다. MCP 도구 호출(Tool call)이 결과를 반환할 때, 프로토콜은 해당 결과의 내용을 모델의 컨텍스트 창(Context window)으로 전달합니다. 하지만 이 과정에서 해당 콘텐츠가 어디에서 왔는지, 누가 생성했는지, 또는 전송 과정에서 변조되지 않았는지에 대한 암호학적으로 증명 가능한 정보(Cryptographically attestable information)는 함께 전달하지 않습니다. 모델은 tool_result를 전달받고 그 내용에 따라 어떻게 행동할지 결정해야 하지만, 그 내용은 신뢰할 수 있는 서버, 침해된 서버, DNS 리바인딩(DNS-rebinded)된 엔드포인트, 또는 공격자가 제어하며 모델의 동작을 무력화하도록 설계된 지시문(Instruction text)을 채워 넣은 웹페이지로부터 올 수 있습니다.
MCP 명세(Specification)에는 클라이언트에게 도구의 속성을 전달하기 위한 목적으로 readOnlyHint, destructiveHint, idempotentHint와 같은 필드를 포함하는 ToolAnnotations 객체가 포함되어 있습니다. 명세에는 이러한 어노테이션(Annotation)이 권고 사항(Advisory)일 뿐 보안 경계(Security boundaries)가 아니라고 명시되어 있습니다. 이들은 서버에 의해 설정될 수 있으며, 실제 도구 동작과 검증 가능한 결합(Verifiable binding)을 갖지 않습니다. 악의적이거나 침해된 서버는 파괴적인 쓰기 작업(Destructive write operation)을 readOnly로 어노테이션할 수 있습니다. 지시문이 주입된(Instruction-injected) 도구 결과는 텍스트 내에 조작된 어노테이션을 포함할 수 있습니다. 클라이언트와 모델 모두 이를 암호학적으로 검증할 수 없습니다.
그 결과, 프로토콜이 신뢰할 수 있는 출처 신호(Provenance signal)를 전혀 제공하지 않는 콘텐츠에 대해 모델이 신뢰 결정을 내리도록 요구하는 프로토콜이 만들어졌습니다.
공격 표면: Fetch 서버 및 DNS 리바인딩
레퍼런스 MCP fetch 서버 — 웹 브라우징 도구 호출을 위해 Anthropic에서 공식적으로 유지 관리하는 서버 — 는 URL을 수락하여 콘텐츠를 가져오고, HTML을 마크다운(Markdown)으로 변환한 뒤 이를 tool_result로 반환합니다. 모델은 이 마크다운을 전달받아 컨텍스트의 일부로 처리합니다.
가져오려는(fetching) URL이 공격자에 의해 제어되는 경우 어떤 일이 발생하는지 생각해 보십시오. 공격자는 페이지에 임의의 텍스트를 배치할 수 있습니다. 여기에는 시스템 프롬프트(system-prompt)나 도구 정의(tool-definition) 콘텐츠처럼 보이도록 형식화된 지침, 모델의 컨텍스트 내 다른 도구 이름을 참조하며 특정 인자(arguments)와 함께 호출하도록 모델에게 지시하는 텍스트, 허위 컨텍스트를 구축하기 위해 정당한 도구 결과(tool results)의 형식을 모방한 콘텐츠, 그리고 후속 URL 가져오기(URL fetch) 시 정보를 인코딩하여 컨텍스트로부터 정보를 유출(exfiltrate)하도록 하는 지침 등이 포함될 수 있습니다.
이는 가설이 아닙니다. 가져오기 서버(fetch server)는 웹 콘텐츠를 신뢰할 수 없는 외부 콘텐츠로 정화(sanitizing)하거나 라벨링하지 않고 마크다운(Markdown)으로 변환합니다. 즉, 이 콘텐츠는 시스템 지침(system instructions)이나 정당한 도구 결과와 동일한 구조적 비중을 가지고 모델의 컨텍스트에 안착합니다. 모델에는 "이것은 외부 페이지에서 가져온 콘텐츠이다"와 "이것은 운영자(operator)로부터 온 지침이다"를 구분할 수 있는 신뢰할 수 있는 메커니즘이 없습니다.
이 공격은 MCP 서버를 침해할 필요가 없습니다. 모델이 가져오도록 요청받을 URL에 콘텐츠를 제공할 수 있는 능력만 있으면 됩니다. 많은 에이전트 워크플로우(agentic workflows)에서 이는 사용자 입력에 의해 직접 제어되거나, 이전에 가져온 문서 내의 공격자 제어 콘텐츠에 의해 제어됩니다.
MCP를 대상으로 하는 DNS 리바인딩(DNS rebinding) 공격은 별개의, 그리고 특히 위험한 공격 경로를 생성합니다. 공격자는 도메인을 등록하고, 처음에는 해당 도메인을 공인 IP(public IP)로 해석(resolve)하는 DNS 서버를 구성합니다. MCP 가져오기 서버는 URL을 확인하고, 이것이 공인 IP로 해석되며 모든 허용 목록(allowlist) 또는 차단 확인을 통과하면 절차를 진행합니다. 그 후 공격자의 DNS 서버는 TTL을 0으로 떨어뜨리고 도메인을 내부 IP 주소(192.168.x.x, 10.x.x.x, 또는 172.16-31.x.x)로 다시 바인딩(rebind)합니다. 이는 일반적으로 MCP 서버가 자신의 네트워크 위치에서 도달할 수 있는 내부 서비스의 IP입니다. MCP 서버가 HTTP 요청을 보낼 때, DNS 조회(DNS lookup)는 이제 내부 IP로 해석됩니다. 가져오기 서버는 내부 서비스에 연결하고 그 콘텐츠를 모델에게 반환합니다.
이는 대부분의 URL 기반 필터링을 우회합니다. 필터링이 가져오기(fetch) 시점(내부 IP)이 아니라 허용 목록(allowlist) 확인 시점(공용 IP)에 이루어지기 때문입니다. MCP 서버는 내부 서비스에 대한 비자발적인 프록시(proxy)가 되며, 공격자는 이제 모델이 해당 내부 서비스의 출력값을 읽도록 만들 수 있습니다.
이러한 취약점(footgun)은 MCP 서버가 네트워크 경계 내부에서 실행되며, 공개적으로 노출되지 않은 내부 API, 문서 시스템, 내부 대시보드 또는 구성 관리 엔드포인트(configuration management endpoints)에 접근할 수 있는 셀프 호스팅 에이전트 배포(self-hosted agentic deployments) 환경에서 특히 치명적입니다.
탐지 규칙 및 완화 조치 (Detection Rules and Mitigations)
다음은 MCP 배포를 위한 구체적이고 로그 기록이 가능한 신호들입니다. 이는 MCP 프록시 계층, SIEM 규칙 또는 에이전트 모니터링 인프라에서 구현되어야 합니다.
지시문 인젝션(Instruction injection) 탐지:
- 규칙: 도구 결과(tool result) 콘텐츠에 시스템 프롬프트(system-prompt)와 유사한 구조가 포함됨.
tool_result페이로드에 시스템 프롬프트 형식 패턴과 일치하는 문자열이 포함될 경우 경고를 발생시킵니다: XML 스타일의 역할 태그(<system>,<instructions>,[INST]), 지시문을 프레임화하는 마크다운 헤더(## New Instructions,## Override), 또는 모델 역할에 대한 명시적 참조 등. - 규칙: 도구 결과가 인자(arguments)와 함께 다른 도구 이름을 참조함.
tool_result의 텍text 콘텐츠에 현재 MCP 세션에 등록된 도구 이름과 일치하는 문자열이 포함되어 있고, 특히 그 뒤에 인자와 유사한 구조가 뒤따를 경우 경고를 발생시킵니다. - 규칙: 도구 결과 크기가 요청 대비 임계값을 초과함. 상대적으로 단순한 URL에 대한 가져오기(fetch) 작업에서 발생하는 대용량 도구 결과는 인젝션 텍스트가 채워진 콘텐츠임을 나타낼 수 있습니다.
DNS 리바인딩(DNS rebinding) 탐지:
- 규칙: MCP fetch의 목적지 IP가 RFC1918 공간으로 해석됨. URL 파싱 시점이 아닌, HTTP 연결 시점의 해석된 IP 주소를 기록합니다. 비공개 호스트네임(non-private hostname)에 대한 fetch가 10.0.0.0/8, 172.16.0.0/12 또는 192.168.0.0/16으로의 TCP 연결로 이어질 경우 경고를 발생시킵니다.
- 규칙: MCP로 fetch된 도메인의 DNS TTL이 임계값 미만임. MCP fetch 서버에 의해 수행된 모든 DNS 해석(DNS resolution)의 TTL 값을 기록합니다. CDN이 아닌 도메인에서 TTL이 0이거나 30초 미만인 경우, 이는 리바인딩(rebinding) 준비 신호입니다.
- 규칙: 내부 IP로 끝나는 HTTP 리다이렉트 체인. 공용 IP로의 초기 fetch가 결과적으로 내부 엔드포인트로 리다이렉트되는 리다이렉트 체인(redirect chains)을 탐지합니다.
행동 이상 탐지(Behavioral anomaly detection):
- 규칙: 도구 호출(Tool call) 시퀀스가 확립된 세션 패턴에서 벗어남. fetch_url 결과 직후에 새로운 도구 호출 유형이 나타날 경우 경고를 발생시킵니다. 이는 성공적인 인젝션(injection)과 일치하는 패턴입니다.
- 규칙: 사전 사용자 메시지 없이 권한이 있는 쓰기/실행 도구를 호출함. 해당 호출을 트리거한 대화 차례(conversation turn)에서 상응하는 사용자 지침 없이 파괴적이거나 쓰기 기능이 있는 도구가 호출되는 경우 검토 대상으로 표시합니다.
- 규칙: 체인된 fetch 호출을 통한 데이터 유출(Data exfiltration). fetch_url 도구 호출에 이전 도구 결과나 컨텍스트에 존재하던 문자열을 포함하는 URL 쿼리 파라미터 또는 프래그먼트(fragment)가 포함된 경우 경고를 발생시킵니다.
탐지 이외의 완화 조치(Mitigations beyond detection):
- 컨텍스트 내에서 신뢰할 수 없는 콘텐츠를 명시적으로 라벨링함. 모델 프롬프트 아키텍처(model prompt architecture)는 외부 소스로부터 온 도구 결과를 신뢰할 수 없는 것으로 명확히 구분해야 합니다. 외부 fetch 결과를
<external_content source="untrusted">와 같은 구조화된 태그로 감싸고, 모델이 해당 콘텐츠를 명령(instruction)이 아닌 데이터(data)로 취급하도록 훈련하거나 프롬프팅하는 것은 인젝션 위험을 줄여주지만 완전히 제거하지는 못합니다.
주의 깊게 살펴봐야 할 사항
Anthropic이 이 취약점 공개에 어떻게 대응하는지 주시하십시오. MCP 명세(spec)에 출처(provenance) 필드를 추가할지, 아니면 fetch 서버에 보안 중심의 업데이트를 출시할지 지켜봐야 합니다. 또한, 제3자 MCP 구현체들이 프롬프트 아키텍처(prompt architectures)에 신뢰 레이블링(trust-labeling) 패턴을 채택하는지도 모니터링해야 합니다.
출처: dev.to
[7월 14일 업데이트, devto_mcp를 통해]
Faruk Kolip이 약 600줄의 TypeScript로 구축한 X (Twitter)용 새로운 제3자 MCP 서버는, 단순하고 감사 가능한(auditable) MCP 구현체라도 빠르게 채택될 수 있음을 보여줍니다(2주 만에 npm 다운로드 500회 이상). 하지만 [Faruk Kolip에 따르면] 이 서버는 인증이 없는 공개된 미문서 JSON 엔드포인트(cdn.syndication.twimg.com/tweet-result)에 의존하고 있습니다. 이 서버는 순수 함수(pure functions)를 사용하며, 데이터베이스나 세션 상태(session state)가 없고, npx를 통한 무설치 실행을 위해 npm을 통해 배포됩니다. 이 실제 사례는 REST API 대비 MCP의 배포 우위를 강조하는 동시에, 많은 MCP 서버가 문서화되지 않고 변경되기 쉬운 데이터 소스에 기반하여 구축되어 있다는 점을 부각하며 혼동된 대리인(confused deputy) 위험을 증폭시킵니다. 즉, 이러한 소스가 침해되거나 변경될 경우, 인젝션된 콘텐츠가 모델의 컨텍스트(context)로 직접 흘러 들어가게 됩니다.
원문 게시: gentic.news
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기