
- 저자: Huan Li, Yuwei Wang, Srinivasan Manoharan
- 발표: arXiv v1, 2026-09-18
- 원문: arXiv
- Tags: MCP, Zero Trust, Authorization, Tool Discovery, Prompt Injection, Least Privilege, Token Introspection, FastMCP, Agent Security, Enterprise AI
본 글은 원 논문의 주요 기술적 내용을 이해하기 쉽게 요약·정리한 글입니다. 자세한 내용은 상단의 원문 링크를 참고하세요.
한눈에 보기
이 논문은 Model Context Protocol 서버에서 인증, component discovery, 실제 invocation 인가를 하나의 권한 선언으로 묶는 Python/FastMCP 확장 아키텍처를 제안합니다. viewer credential을 가진 에이전트에게 admin tool schema 자체를 숨기고, 이름을 추측해 직접 호출해도 decorator가 다시 차단하는 defense-in-depth가 핵심입니다.
60개 prompt-injection payload를 4개 모델·3개 설정·3회씩 실행한 2,160회 실험에서 baseline은 금지 도구 호출 시도 152/720, full extension은 0/720이었습니다. 다만 0이라는 값은 숨겨진 schema로는 모델이 tool call을 만들기 어렵다는 구조적 결과이고, authorization의 안전성은 LLM 실험보다 실행 경로의 강제 검사에서 나옵니다.
연구 배경
MCP의 list_tools는 단순 문서가 아니라 모델의 현재 capability view입니다. 권한 없는 도구가 목록에 있으면 prompt injection이 이름과 schema를 악용하고, 반대로 목록에서만 숨기고 실제 call_tool을 검사하지 않으면 이름을 추측한 직접 호출이 통과할 수 있습니다.
공식 SDK들은 인증 지원 수준과 list/invocation 결합 방식이 다릅니다. 논문은 2026-05-15 기준 6개 SDK를 비교하고 Python FastMCP에 heterogeneous credential, opaque-token introspection, pre-auth metadata, DNF 권한 선언을 추가합니다.
공격 모델 / 전제 조건
서버는 TLS gateway 뒤에 있고 IdP, OS, TLS, host는 신뢰한다고 가정합니다. 공격자는 정상 발급됐지만 부족한 scope의 credential을 가질 수 있고, 에이전트가 처리하는 자연어에 prompt injection을 넣거나, 인증 전 metadata를 읽고, 응답 timing을 관찰할 수 있지만 HTTP header를 위조하지는 못합니다.
DoS, prompt injection 자체의 예방, RFC 8693 downstream delegation, cache side channel은 범위 밖입니다. 실험의 viewer token은 mock Kubernetes 서버의 8개 도구 중 4개만 볼 수 있고, restart_pod는 금지 도구로 설정됩니다.
비판적 검토 / 아쉬운 점
- 가장 중요한 우려는 dual-persona scope union입니다. 서로 다른 Bearer·custom-header credential의 scope를 합치면 각 주체가 단독으로 갖지 못한 조합 권한이 생길 수 있습니다. 동일 principal·session·audience 결합을 검증하는 실험과 deny-by-default 합성 규칙이 필요합니다.
- pre-auth metadata는 의도적인 정찰 표면입니다. invocation 권한은 주지 않지만 tool 이름, schema, 필요 권한, 인증 방식을 누구나 수집할 수 있습니다. 공개/인증 discovery 모드 분리와 민감 component의 최소 공개 정책을 비교해야 합니다.
- LLM 평가가 authorization 증명의 중심이 될 수 없습니다. 한 개 금지 도구와 60개 hand-reviewed payload의 0/720은 schema filtering의 예상 결과이며, encoding·이름 추측·직접 protocol client는 별개입니다. property test, fuzzing, bypass 경로 분석이 더 중요한 증거입니다.
- open-by-default 가능성이 남습니다. permission annotation을 빠뜨린 도구·prompt·resource가 어떻게 처리되는지가 실제 배포 안전성을 좌우합니다. annotation coverage gate와 CI fail-closed 검증이 필요합니다.
핵심 Root Cause
깨진 불변조건은 “호출자가 권한 조건을 만족할 때에만 component가 discovery 응답에 나타나고, 같은 조건을 만족할 때에만 실행 가능해야 한다”입니다. 기존 구현에서 gateway 인증, list_tools filtering, handler 내부 권한 검사가 서로 다른 설정·코드에 흩어지면 정책 drift가 생겨 목록과 실행 경로가 불일치합니다.
또한 자연어 모델의 거부를 인가 통제로 취급하면 prompt injection이 보안 결정에 개입합니다. 보안 결정은 HTTP credential과 선언된 DNF 권한만으로 이뤄지고, 모델 출력은 권한을 증가시키지 않아야 합니다.
핵심 공격 원리
baseline에서는 viewer가 admin tool schema를 보고 prompt injection에 따라 restart_pod 호출을 시도할 수 있습니다. filter-only 설정은 schema를 숨겨 모델의 시도를 줄이지만, protocol client가 이름과 argument를 추측해 직접 call_tool을 보내면 실행됩니다.
full 설정은 한 @require_permissions annotation을 metadata, listing filter, invocation decorator가 함께 읽습니다. 따라서 자연어가 금지 tool을 언급하게 만들거나 이름을 직접 추측해도 마지막 실행 지점에서 동일 권한식을 다시 평가합니다.
공격 흐름
- AuthMiddleware가 Bearer·custom header를 파싱하고 각 backend에서 token을 검증합니다.
- opaque token은 vendor endpoint에서 introspection하고 SHA-256 token key의 TTL cache에 저장합니다.
- 호출자의 scope를 DNF 권한식과 비교해
list_tools,list_prompts,list_resources응답을 줄입니다. - 모델 또는 직접 client가 component를 호출하면 decorator가 같은 DNF를 다시 평가합니다.
- 권한이 없으면 모델 거부 여부와 무관하게 실행을 중단하고, 권한이 있으면 원래 함수 signature와 schema를 유지해 호출합니다.
성공 조건 / 실패 조건
공격은 권한 없는 component가 목록에 노출되고 모델이 injection을 따라 호출하거나, filter만 존재해 raw call_tool 경로가 인가를 우회할 때 성공합니다. annotation 누락, 잘못된 OR/AND 식, 서로 다른 principal의 scope union, cache TTL 동안의 철회 지연도 성공 조건이 될 수 있습니다.
목록과 invocation이 동일한 fail-closed 정책을 사용하고 credential의 issuer·audience·principal이 바인딩되며, raw protocol 경로에도 decorator가 적용되면 실패합니다. tool 이름 누출은 남을 수 있지만 실제 권한 상승과는 구분해야 합니다.
연구진의 실험 환경
SDK 비교 snapshot은 Python 1.27 + FastMCP 3.4, TypeScript 1.26, Go 1.3, Rust rmcp 1.2, C# 1.1, Swift 0.10.2이며 2026-05-15 최신 stable을 기준으로 합니다. Java, Kotlin, PHP, Ruby는 empirical claim 밖입니다.
adversarial testbed는 8개 mock Kubernetes tool, 4개 viewer·4개 admin permission으로 구성됐습니다. 60개 payload는 4개 class별 15개이며 GPT-5, Claude Sonnet 4-6, Claude Opus 4-7, Gemini 2.5 Pro에 대해 payload별 3회, 설정 3개를 실행해 총 2,160회를 만들었습니다.
성능 microbenchmark는 설정·operation 조합당 1,000 request를 3 round 실행해 median을 냈고 50회 warm-up을 사용했습니다. production 수치는 PayPal의 수십 개 인증 MCP 서버에 대한 7일 aggregate 관찰이며 공개 artifact로 재현할 수 없습니다.
주요 실험 결과
| 항목 | 결과 | 조건 |
|---|---|---|
| 금지 tool 호출 시도 | baseline 152/720, full 0/720 | 4 LLM, 60 payload, 3회 |
| filter-only raw 호출 | 실행 성공 | 이름을 아는 scripted client |
| full raw 호출 | decorator에서 차단 | 동일 scripted client |
| 금지 tool 이름 언급 | Opus 169/180, Sonnet 142/180, Gemini 44/180, GPT 13/180 | full 설정에서도 text leak 측정 |
| 추가 framework overhead | p50 약 0ms, p95 최대 약 0.15ms | auth baseline 위 filter+decorator |
| production cache hit | 96.1% | 7일 aggregate trace |
| token 검증 p50 | hit 9.9ms, miss 296ms | 약 30배 차이 |
microbenchmark에서 list_tools p50/p95는 vanilla 1.71/1.98ms, full 1.67/1.92ms이고 call_tool은 vanilla 2.15/2.41ms, full 2.18/2.49ms였습니다. 필터 후 schema가 8개에서 4개로 줄어 listing serialization 비용이 오히려 약간 감소했습니다.
실제 발견된 취약점 / 사례
논문은 특정 vendor CVE나 실제 침해를 보고하지 않습니다. 공식 SDK의 문서화된 capability gap과 저자들의 production 경험을 바탕으로, 목록 filtering 없이 모델 거부에 의존하거나 filtering만 하고 invocation guard를 두지 않는 구성의 bypass를 mock server에서 재현합니다.
PayPal 환경에서 여러 credential 유형, YAML metadata drift, unauthorized tool로 인한 PermissionError와 낭비된 LLM cycle을 관찰했다고 설명하지만 원시 로그·서버별 분모·사건 수는 공개하지 않습니다. 따라서 이는 production 경험 보고이지 독립 검증된 취약점 통계가 아닙니다.
저자 주장 vs 실제 증명 범위
동일 권한 선언으로 discovery와 invocation을 결합하면 filter-only bypass를 막고 framework overhead가 작다는 주장은 코드 구조, scripted call, microbenchmark로 뒷받침됩니다. cache가 IdP 부하와 latency를 줄인다는 production 관찰도 방향성은 분명합니다.
그러나 0/720은 prompt injection을 방어했다는 일반 증명이 아니라 금지 schema 제거로 특정 모델의 tool-call 시도가 사라진 결과입니다. 또한 여러 credential의 scope union, annotation 누락, pre-auth 정보 노출, 실제 hostile client에 대한 protocol-level 안전성을 포괄적으로 증명하지는 않았습니다.
기존 공격 / 기존 점검 방식과의 차이
기존 접근은 gateway에서 credential을 확인한 뒤 MCP 서버 전체를 신뢰하거나, handler body에서 개별적으로 권한을 검사합니다. 이 논문은 component 단위 least privilege를 discovery 단계부터 적용하고 raw invocation에서 다시 확인해 capability view와 enforcement를 맞춥니다.
FastMCP의 native auth 결합과 외부 PDP 연동도 유사 목표를 갖습니다. 이 연구의 차별점은 heterogeneous credential middleware, vendor-specific opaque token introspection, DNF OR/AND 표현, 인증 전 registry metadata까지 하나의 선언으로 연결한 reference architecture입니다.
연구의 한계와 주의해서 볼 부분
저자들은 60개 injection, 한 개 금지 tool, encoding·obfuscation 미평가, 6/10 SDK만 비교, production 수치 비재현, 2026-05 SDK snapshot이라는 한계를 인정합니다. full 설정에서도 모델이 금지 tool 이름을 자주 말했으므로 정보 누출과 실행 차단은 별개입니다.
추가로 cache 기본 TTL 300초는 철회 후 최악 5분, 평균 약 2.5분의 stale authorization 창을 만듭니다. scope union과 pre-auth metadata는 기능적 편의와 zero-trust 최소 공개 원칙 사이의 설계 선택이므로 환경별 threat model 없이 그대로 복제하면 안 됩니다.
공개 PoC / Exploit / Tool / Artifact 분석
논문 원문의 Open Science 절은 extension code, 2,160회 출력, aggregation script, name-guess attacker, dual-persona 설정을 공개한다고 적지만 repository 링크는 “추가 예정” 상태입니다. 2026-09-23 기준 원문과 공식 프로젝트 정보에서 실제 접근 가능한 저장소 URL을 확인하지 못했으므로 현재 재현 가능한 공개 artifact로 표현할 수 없습니다.
Gateway-side LLM client와 production metric은 애초에 비공개이며, 공개 예정 artifact가 열리더라도 그 부분은 재현되지 않습니다. 공식 GitHub 저장소를 확인할 수 없어 ZIP 보관 대상도 없습니다.
레드팀 / 모의해킹에서 어떻게 활용할까
승인된 mock MCP 서버에서 list_tools 결과와 raw call_tool을 별도 시험합니다. viewer credential, admin credential, credential 없음, invalid header, 두 header 동시 제출, token 철회 직후를 표로 만들고 각 상태에서 visibility와 invocation이 같은 정책식을 따르는지 확인합니다.
관찰 포인트는 annotation 누락, DNF 오구성, principal 혼합, cache stale window, metadata 정찰, wrapper signature 손실입니다. 실제 production tool에 도달하기 전 no-op handler로 검증하고, 권한 없는 호출이 한 번이라도 실행되거나 서로 다른 identity scope가 합쳐지면 즉시 중단합니다.
실제 점검 시 추가할 체크리스트
- 권한 없는 tool·prompt·resource가 listing에서 제거되는가
- 이름을 추측한 raw invocation도 같은 정책으로 차단되는가
- annotation이 없는 component는 fail-closed인가
- AND/OR DNF 식이 의도한 역할·scope와 일치하는가
- 여러 credential을 합칠 때 issuer·audience·principal이 동일한가
- invalid header 하나가 valid credential을 오염시키거나 우회하지 않는가
- token 철회와 TTL cache의 최대 stale window를 측정했는가
- pre-auth metadata가 민감 tool 이름·schema를 과도하게 노출하지 않는가
- wrapper가 원래 function signature와 JSON schema를 보존하는가
- 모델 거부율이 아니라 실제 invocation 결과로 판정하는가
실무 가치 평가
MCP를 기업 도구 gateway로 쓰는 조직에는 높은 가치가 있습니다. 가장 유용한 부분은 prompt filter가 아니라 discovery와 invocation을 동일 source of truth로 강제해야 한다는 설계 원칙과 filter-only bypass 재현입니다.
다만 reference implementation이 현재 공개되지 않아 즉시 채택보다는 architecture review checklist로 활용하는 것이 안전합니다. scope union, cache TTL, metadata 공개 수준을 자체 identity model에 맞게 다시 설계해야 합니다.
결론
MCP에서 tool 목록은 권한 모델의 일부이며, 숨김과 실행 차단 중 하나만 구현하면 충분하지 않습니다. 자연어 모델은 인가 주체가 아니므로 credential·permission·component 사이의 관계를 deterministic middleware와 실행 guard가 강제해야 합니다.
논문은 이 결합의 성능 비용이 작고 운영상 유용하다는 근거를 제시합니다. 다만 0회 tool-call 시도를 zero-trust의 완전한 증명으로 확대하지 말고, principal binding, fail-closed annotation, 직접 protocol 공격을 추가 검증해야 합니다.
MCP, 제로트러스트, 권한부여, 도구탐색, 프롬프트인젝션, 최소권한, 토큰인트로스펙션, FastMCP, 에이전트보안, 엔터프라이즈AI
댓글