본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 18. 22:15

12개의 인기 MCP 서버를 스캔했습니다. 가장 흥미로운 발견은 우리의 자체 오탐(False Positives)이었습니다.

요약

보안 스캔 도구인 mcp-customs를 통해 12개의 인기 MCP 서버를 분석한 결과, 대부분의 서버가 권한 선언을 누락하고 있음을 발견했습니다. 또한 테스트 코드와 런타임 코드를 구분하지 못하는 스캐너의 오탐(False Positives) 사례를 통해 보안 도구의 한계를 지적합니다.

핵심 포인트

  • 대부분의 MCP 서버가 매니페스트에 권한 및 범위 선언을 누락함
  • 테스트/개발용 코드와 실제 런타임 코드를 구분하는 것이 보안 분석의 핵심
  • 주석 처리된 코드를 취약점으로 오인하는 등 휴리스틱 스캐너의 한계 존재
  • MCP 서버 구축 시 필요한 권한(파일 시스템, 네트워크 등)을 명시할 것을 권장

우리는 MCP 서버를 설치하기 전에 일반적인 보안 위험을 점검할 수 있는 무료 오프라인 CLI인 mcp-customs를 구축했습니다. AI 에이전트가 연결하는 서버를 위한 npm audit이라고 생각하면 됩니다. 누군가에게 사용을 권장하기 전에, 우리는 12개의 실제 인기 MCP 서버를 대상으로 스캔을 진행하고 모든 발견 사항을 수동으로 검토했습니다. 실제로 확인된 내용은 다음과 같습니다.

설정 (The setup)

우리는 GitHub에서 별(Star) 개수 기준으로 현재 가장 인기 있는 MCP 관련 리포지토리(repos)를 가져왔으며, 특정 항목을 골라내지 않고 각 항목을 있는 그대로 스캔했습니다:

서버 (Server)별 (Stars)점수 (Score)승인 (Stamp)
github/github-mcp-server30.8k97/100CLEARED
...
*아래 참조 — 이 두 점수는 보이는 의미와 다를 수 있습니다.

발견 #1: 거의 아무도 권한을 선언하지 않음

12개의 서버 중 11개는 매니페스트(manifest)에 권한(permission)이나 범위(scope) 선언이 전혀 없었습니다. "취약한" 선언이 아니라, 아예 없었습니다. 이것은 특정 프로젝트에 대한 순위 매기기가 아닙니다. 현재로서는 이에 대한 실질적인 관례가 없습니다. 만약 여러분이 MCP 서버를 구축하고 있다면, 서버가 실제로 무엇을 필요로 하는지(파일 시스템(filesystem)? 네트워크(network)? 셸(shell)?)를 선언하는 것이 클라이언트의 "이것을 허용하시겠습니까?"라는 프롬프트가 의미를 갖게 만드는 가장 쉬운 방법입니다.

발견 #2: 우리 자신의 스캐너가 더 큰 이야기였습니다

무엇인가를 발표하기 전에, 우리는 모든 발견 사항을 "런타임 코드(runtime code)" 대 "테스트/개발/스크립트 코드(test/dev/script code)"로 나누었습니다. 테스트 픽스처(test fixture)에 있는 subprocess.run(shell=True)는 요청 핸들러(request handler)에 있는 동일한 코드 라인과는 매우 다른 의미를 갖기 때문입니다. 그렇게 분류한 결과:

  • pal-mcp-server는 13개의 탐지 결과(findings)를 기록하며 0/100점을 받았습니다. 모든 결과가 tests/ 또는 simulator_tests/에 있었습니다. 이는 _개인정보(PII) 정화기(sanitizer)_를 테스트하기 위해 사용된 가짜 API 키와, 보안 감사 기능을 테스트하는 과정에서의 shell=True 호출이었습니다. 런타임 코드(Runtime-code) 탐지 결과는 0개였습니다.
  • shadcn-ui-mcp-server 또한 0/100점을 기록했습니다. 3개의 탐지 결과 중 2개는 릴리스 버전 관리 스크립트(scripts/bump-version.js) 내의 execSync() 호출이었습니다. 이는 에이전트(agent)가 도달할 수 있는 코드가 아니라, 관리자가 npm version을 실행할 때만 사용되는 코드입니다.
  • 우리는 프로세스 도중 우리 자신의 버그도 발견했습니다. 스캐너가 처음에 notion-mcp-server 내의 주석 처리된 eval() 호출을 심각(critical) 단계로 분류했습니다. 해당 코드는 // 주석 안에 있었습니다. 이 포스트의 다른 내용을 다시 실행하기 전에 주석 제거(comment-stripping) 로직을 수정했습니다. 이 표의 이전 초안은 잘못되었을 것입니다.

테스트 코드와 런타임 코드를 구분하지 못하거나, 주석과 실행문을 구분하지 못하는 휴리스틱 스캐너(heuristic scanner)는 별로 유용하지 않습니다. 우리는 부풀려진 수치를 발표하기보다, 스캐너가 어디서 실패했는지를 보여드리고자 합니다.

발견 사항 #3: 실제로 다시 살펴볼 가치가 있는 두 가지

테스트/개발 노이즈를 걸러낸 후, 유지 관리자가 주의를 기울일 가치가 있다고 판단되는 두 가지 실제 코드 패턴이 남았습니다. 이는 확인된 취약점(vulnerabilities)은 아니지만, 바로 이러한 도구들이 찾아내기 위해 존재하는 전형적인 형태의 사례들입니다:

  • cloudflare/mcp-server-cloudflare, sandbox.container.app.ts: 파일 읽기(file read)와 파일 쓰기(file write) 작업 모두 reqPath라는 이름의 변수를 fs.readFile / fs.writeFile에 직접 전달합니다. 상위 단계에서 제약이 걸려 있는지 확인하기 위해 전체 호출 경로(call path)를 추적하지는 않았습니다. 코드베이스를 아는 사람이라면 5분이면 확인할 수 있는 사항이며, 이것이 바로 확언(asserting)하기보다 플래그(flagging)를 남기는 이유입니다.
  • notion-mcp-server, src/init-server.ts: 시작 시점에 결정된 경로에서 스펙(spec) 파일을 읽습니다. 위험도는 더 낮습니다. 에이전트의 도구 호출(tool call)이 제어하는 것이 아니라 로컬 설정 경로로 보이지만, 동일한 범주에 속합니다.

'CLEARED' 점수를 받았거나 높은 점수를 받은 나머지 모든 항목은 기껏해야 #1에서 언급한 권한 누락(missing-permissions) 탐지 결과뿐이었습니다.

오늘 MCP 서버를 선택할 때 이것이 의미하는 바

위 표의 점수를 안전 순위(safety ranking)로 읽지 마십시오. 우선 발견 사항 #2를 먼저 읽어보시기 바랍니다. 이와 같은 휴리스틱(heuristic) 도구에서 'FLAGGED(경고)' 표시가 떴다는 것은 "확인해 보라"는 뜻이지, "설치하지 마라"는 뜻이 아닙니다. 오늘 발견된 'FLAGGED' 결과 중 몇몇은 해당 도구가 테스트 디렉터리가 런타임 경로(runtime path)가 아니라는 점을 이해하기만 했어도 'CLEARED(해제)' 되었을 것입니다. 이는 프로젝트의 결함이 아니라 도구의 한계입니다.

사용해 보기

npx mcp-customs scan ./path-to-some-mcp-server

완전한 오프라인 상태, 텔레메트리(telemetry) 없음, 무료, Apache-2.0 라이선스입니다. 규칙과 스캐너 자체는 약 250줄 정도입니다. 5분이면 모두 읽을 수 있으며, 이는 대부분의 보안 도구에 대해서는 할 수 없는 말입니다.

만약 위 서버 중 하나를 관리하고 있으며 탐지 결과에 대한 해석(또는 반박)에 도움이 필요하다면 이슈(issue)를 생성해 주세요. 만약 다른 MCP 서버를 관리하고 있으며 저희가 하기 전에 직접 실행해 보고 싶다면, 그것이 바로 이 도구의 핵심 목적입니다. 저희가 공개적으로 귀하의 오탐(false positives)을 찾아내는 것보다, 귀하가 직접 자신의 오탐을 찾는 것을 더 권장합니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0