MCP 서버 보안: 2026년 실용 체크리스트
요약
MCP 서버를 에이전트의 권한 경계로 간주하고 보안 체크리스트를 제시합니다. 도구 정의 표류 방지, 파일 시스템 접근 범위 제한, 환경 변수 내 비밀 정보 노출 최소화 등 프로덕션에서 발견된 5가지 실패 모드를 분석하며 안전한 아키텍처 설계를 강조합니다.
핵심 포인트
- 도구 스키마는 고정(해시)하고 버전 관리를 통해 변경을 추적해야 합니다.
- 파일 시스템 도구는 프로젝트 루트에 한정하여 범위를 극도로 좁혀야 합니다.
- 민감한 비밀 정보는 에이전트 경계가 아닌 서버 자체의 비밀 저장소에서 관리해야 합니다.
- 아웃바운드 통신은 반드시 허용 목록(allowlist) 방식으로 제한해야 합니다.
MCP 서버는 엔드포인트가 아닌 도구를 노출하기 때문에 무해해 보입니다. 클라이언트는 도구를 호출하고 결과를 받습니다. 하지만 이 도구들은 종종 파일 시스템, 데이터베이스, 패키지 관리자 또는 배포 API에 접근합니다. 이는 계획했든 안 했든 MCP 서버를 권한 경계(authorization boundary)로 만듭니다.
여기 제가 프로덕션 환경에서 발견했던 다섯 가지 실패 모드와 에이전트에게 서버를 노출하기 전에 점검할 수 있는 짧은 체크리스트가 있습니다.
도구 정의 표류 (Tool-definition drift)
클라이언트는 도구의 선언(declaration): 이름, 설명, 매개변수 스키마를 읽음으로써 해당 도구가 무엇을 하는지 결정합니다. 만약 이 선언이 거짓이거나 핸들러가 실제로 수행하는 것과 다르게 표류한다면, 클라이언트의 정책은 잘못된 것을 강제하게 됩니다.
실제 예시: "이 경로의 파일을 읽기"로 선언되었지만 실제로는 로그 스트림을 조용히 추적(tails)하는 도구; 핸들러가 설치를 수행하는 --resolve 플래그도 허용하는 "패키지 목록 보기" 도구; 클라이언트의 선언에는 언급되지 않았지만 서버 측에서 추가되어 에이전트가 계속 전송하는 매개변수.
완화 방안: 클라이언트는 자신이 승인한 도구 스키마를 고정(해시)하고, 라이브 선언이 이와 다르게 벗어나는 핸들러는 거부해야 합니다. 서버 측에서는 도구 매니페스트에 버전을 부여하고 모든 선언 변경을 기록해야 합니다. 선언 업데이트는 종속성 증가(dependency bump)를 처리하는 방식과 동일하게 취급해야 합니다. 이는 권한 표면(authority surface)이기 때문입니다.
과도하게 광범위한 파일 시스템 도구 (Over-broad filesystem tools)
모든 경로를 허용하는 파일 시스템 도구는 /etc/shadow, ~/.ssh 및 마운트된 모든 비밀 정보에 접근할 수 있는 파일 시스템 도구와 같습니다. 저는 MCP 서버가 단일 read_file(path)과 단일 write_file(path, content)만을 제공하고 클라이언트에게 안전한 경로를 전달하도록 의존하는 경우를 보았습니다.
클라이언트는 에이전트입니다. 에이전트는 목표를 부여받습니다. 만약 목표가 "배포 수정"이고 에이전트가 모든 경로를 허용하는 write_file을 가지고 있다면, 목표에 도달하는 가장 짧은 경로는 때때로 /etc나 CI 파이프라인이 읽는 디렉토리에 쓰는 것일 수 있습니다.
도구 범위를 좁히세요. read_project_file(glob)과 write_project_file(glob, content)는 리포지토리 루트에 한정하고, 프로젝트 외부의 모든 것을 처리하기 위한 별도의 명시적 도구를 만드세요. 파일 시스템의 나머지는 기본값을 '아니오'로 설정하세요.
환경 변수 내 비밀 정보 (Secrets in the environment)
MCP 서버는 프로세스로 실행됩니다. 프로세스는 환경 변수를 상속받습니다. MCP 서버를 컨테이너나 DATABASE_URL, AWS_ACCESS_KEY_ID 또는 서명 키가 포함된 CI 단계 내부에서 실행하는 것은 흔한 일입니다.
'명령어 실행(run command)' 도구나 파일 시스템 도구를 가진 에이전트는 /proc/self/environ을 읽거나 셸이 .env 파일을 작성하는 디렉토리를 나열할 수 있습니다. 서버가 '비밀 정보 읽기(read secrets)' 도구를 제공하지 않았더라도, 제공된 도구들이 결합되어 그렇게 작동합니다.
민감한 변수는 에이전트 경계가 아닌 서버 경계에서 제거하세요. MCP 서버를 최소한 환경으로 실행하고 필요한 것만 전달하세요. 만약 도구가 자격 증명이 필요하다면, 에이전트가 관찰할 수 있는 프로세스 환경을 통하지 않고 서버 자체의 비밀 저장소(secret store)를 통해 전달해야 합니다.
아웃바운드 허용 목록 (Egress allowlists)
URL을 가져오거나, 패키지를 설치하거나, 레지스트리를 호출하는 도구는 MCP 서버를 데이터 유출 또는 공급망 경유지로 만들 수 있습니다. 클라이언트가 해당 도구를 승인했지만, 도구의 네트워크 목적지가 폭발 반경(blast radius)을 결정합니다.
MCP 서버에서 나가는 연결은 신뢰할 수 없는 입력을 처리하는 모든 서비스에서 나가는 연결처럼 취급해야 합니다. 즉, 목적지의 허용 목록과 그 외에는 아무것도 없어야 합니다. 패키지 설치는 고정된 레지스트리(pinned registry)로 가야 하고, API 호출은 선언된 호스트로 가야 합니다. 나머지 모든 것은 차단되어야 합니다.
시작하는 데 완전한 아웃바운드 프록시가 필요하지 않습니다. iptables 규칙이나 MCP 서버 프로세스에 대한 컨테이너 런타임의 네트워크 정책만으로도
당신이 재현할 수 없는 것은 방어할 수 없습니다. 서버가 실행하는 모든 도구 호출은 다음 사항과 함께 로깅되어야 합니다: 호출한 클라이언트의 신원, 도구 이름, 입력 매개변수(자격 증명은 마스킹), 결과, 그리고 서버 측 타임스탬프.
로그는 사후에 추가 전용(append-only)으로 되어야 하며, 서버가 실행되는 호스트 외부로 전송되어야 합니다. 만약 에이전트가 해당 호스트에서 파일 시스템 도구를 가지고 있다면, 로그 파일에 쓰기 도구도 가지게 됩니다.
체크리스트
워크로드를 실행하도록 노출하는 모든 MCP 서버에 대해 다음을 수행하세요:
- 클라이언트의 각 도구 선언을 고정(Pin)하고 해시화하며, 이탈하는 핸들러는 거부합니다.
- 광범위한 파일 시스템 도구를 프로젝트 루트로 지정된 경로/글롭 범위 도구로 대체합니다.
- 서버 프로세스 환경에서 비밀 정보를 제거하고, 자격 증명은 서버 자체 스토어를 통해서만 전달합니다.
- 서버의 아웃바운드 연결에 이그레스 허용 목록(egress allowlist)을 적용합니다 (레지스트리 + 선언된 API 호스트만).
- 호출자 신원, 도구, 마스킹된 입력, 결과, 서버 타임스탬프를 포함하여 모든 도구 호출을 로깅하고, 로그는 호스트 외부로 전송합니다.
- 서버의 도구 매니페스트(tool manifest)를 업데이트할 때마다 종속성 버전 업그레이드를 검토하듯이 검토합니다.
MCP 서버는 브라우저에서처럼 신뢰할 수 없는 것은 아닙니다. 오히려 에이전트가 조종할 수 있는 CI 러너와 같습니다. 그러니 그에 맞게 보안을 강화하세요.
저는 에이전트 도구 호출을 위한 오픈 소스 기본 거부(default-deny) 정책 계층인 Cirvix AgentControl을 구축하고 있습니다: https://github.com/CIRVIX/agent-control (다음 명령어로 시도해 보세요: npx @cirvix_ai/agent-control scan).
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기