
주요 AI 코딩 에이전트의 권한 모델 비교 — 그리고 그 누구도 메우지 못한 세 가지 격차
요약
Claude Code, Cursor, Codex 등 주요 AI 코딩 에이전트 6종의 보안 및 권한 모델을 비교 분석합니다. 각 에이전트가 제공하는 샌드박싱과 승인 메커니즘의 장점을 확인하는 동시에, MCP 도구 호출 시 인자(arguments)에 대한 세밀한 제어가 불가능하다는 공통적인 보안 격차를 지적합니다.
핵심 포인트
- 주요 AI 에이전트들은 샌드박싱 등 기본적인 보호 기능을 갖추고 있음
- 데이터 손실 사례 대부분은 사용자가 보호 기능을 비활성화했을 때 발생
- MCP 도구 호출 시 인자(arguments) 수준의 세밀한 규칙 설정이 불가능함
- 도구 승인 방식이 이진적(binary)인 구조적 한계를 공유함
2026년은 코딩 에이전트들이 중요한 것들을 삭제하기 시작한 해였습니다. _"Claude CLI가 내 홈 디렉토리를 삭제하고 Mac을 초기화했다"_라는 제목의 Hacker News 스레드는 255개의 추천과 216개의 댓글을 기록했습니다. Cursor는 "YOLO 모드에서 폭주하여" 자기 자신을 포함한 모든 것을 삭제했습니다. OpenAI의 포럼에서는 Codex가 프로젝트 디렉토리 외부에서 파일을 삭제했다고 사용자들이 보고했습니다 — 휴지통을 거치지 않고 240GB에서 700GB가 사라졌습니다. 한 GitHub 이슈에는 잘못된 정리 작업 중에 로그도 남지 않은 채 약 328,000개의 파일이 삭제된 사례가 기록되어 있습니다.
저는 매일 여러 에이전트를 사용하며, 기본 권한을 본질적으로 신뢰하지 않습니다. 에이전트들이 제 기기에서 셸 명령(shell commands)을 실행하기 시작했을 때, 저는 한 가지 질문에 답하기 위해 지난 며칠 동안 6개의 주요 클라이언트 — Claude Code, Cursor, Codex CLI, VS Code Copilot, Claude Desktop, Devin Desktop — 의 보안 모델을 해부했습니다. 그 질문이란 바로 이것입니다: 에이전트가 위험한 시도를 할 때, 실제로 무엇이 이를 가로막는가?
그 답은 저를 두 번 놀라게 했습니다. 첫째, 기본 보호 기능이 대부분의 사람들이 생각하는 것보다 더 낫기 때문입니다. 둘째, 6개 모델 모두 동일한 세 가지 격차를 공유하고 있기 때문입니다.
먼저 좋은 소식부터: 기본 보호 기능은 실재합니다
공을 돌리자면, 벤더(vendors)들은 바쁘게 움직여 왔습니다:
| 호출당 승인 (Per-call approval) | MCP 도구 _인자(arguments)_에 대한 규칙 | 도구 출력값 정화 (Sanitize tool outputs) | OS 샌드박스 (OS sandbox) | 후크 (Hooks) | |
|---|---|---|---|---|---|
| Claude Code | ✓ | ✗ (도구 이름만) | 후크를 통해 | ✓ | ✓ |
| ... |
Cursor는 허용 목록(allowlisted)에 없는 셸 명령을 기본적으로 Seatbelt/Landlock 샌드박스에서 실행합니다. Codex는 세 가지 샌드박스 레벨과 도구별 MCP 승인 모드를 제공합니다. VS Code는 2주 전(v1.127) 터미널 명령에 대해 기본적으로 커널 수준의 샌드박싱(kernel-level sandboxing)을 활성화했습니다. 그리고 위에서 언급한 공포스러운 이야기들에 대해 솔직해질 필요가 있습니다. 최악의 사례들은 사용자가 보호 기능을 껐을 때 발생했습니다 — Codex의 데이터 손실 보고는 이름 그대로인 danger-full-access 모드에서 발생했습니다.
따라서 문제는 "에이전트에게 브레이크가 없다"는 것이 아닙니다. 문제는 브레이크가 작동하지 않는 지점이 어디냐는 것입니다. 6개의 클라이언트 모두에서 공통적으로 나타나는 세 가지 격차(Gap)가 있습니다.
격차 1: MCP 도구 호출의 _인자(arguments)_에 대한 규칙을 작성할 수 있는 곳이 아무도 없다
VS Code는 전체 명령줄에 대한 정규 표현식(regex) 적용, '거부 우선 허용(deny-overrides-allow)' 등 진정으로 훌륭한 허용/거부 엔진을 갖추고 있습니다. 하지만 이는 오직 **통합 터미널(integrated terminal)**에만 적용됩니다. MCP 도구의 경우, 승인은 이진적(binary)입니다. 즉, 도구를 신뢰하거나 신뢰하지 않거나 둘 중 하나입니다.
동일한 패턴이 모든 곳에서 반복됩니다. Cursor의 MCP 허용 목록(allowlist)은 server:tool 문자열과 일치할 뿐 인자(arguments)는 고려하지 않습니다. Codex는 도구 이름과 어노테이션(annotation)으로 승인합니다. Claude Desktop은 도구당 "항상 허용(Allow always)" 기능만 제공하며 그보다 세밀한 제어는 불가능합니다. Claude Code의 권한 규칙은 이름으로만 MCP 도구와 매칭됩니다. Devin Local은 단어 경계 접두사(word-boundary prefixes)와 매칭하며 정규 표현식은 지원하지 않습니다.
단순히 말하자면: VS Code의 터미널에서는 rm -rf를 차단할 수 있지만, 어떤 클라이언트에서도 MCP 도구 호출 내부의 명령은 차단할 수 없습니다. 그리고 MCP 도구 호출은 독이 든 README 파일이나 악의적인 도구 설명이 에이전트를 공격자로 변질시키는 바로 그 지점입니다. run_command 도구가 마운트되어 있다면 에이전트에게 사용자의 터미널은 필요하지 않습니다.
격차 2: 도구가 _반환하는 내용(return)_을 정화(sanitize)하는 곳이 아무도 없다
모두가 에이전트가 무엇을 _하려 하는지(do)_는 감시합니다. 하지만 에이전트가 무엇을 _읽는지(read)_를 감시하는 곳은 거의 없습니다. 도구의 결과값은 간접 프롬프트 주입(indirect prompt injection)의 정문 역할을 합니다. 가져온 웹페이지, 저장소(repo) 파일, 혹은 _"이전 지침을 무시하고..."_라고 말하는 데이터베이스 행 등이 모든 클라이언트에서 기본적으로 필터링 없이 모델의 컨텍스트(context)로 들어갑니다.
6개 클라이언트 전반에 걸친 네이티브 출력 정화(output sanitization) 기능은: **제로(zero)**입니다. Claude Code와 Cursor는 사용자가 직접 훅(hooks, updatedToolOutput / updated_mcp_tool_output)을 작성한다면 이를 수행할 수 있습니다. 나머지 4개는 아예 메커니즘 자체가 없습니다. Claude Desktop의 Cowork 모드는 모델 기반의 안전 점검(safety check)을 통해 작업을 검토하는데, 이는 아무것도 없는 것보다는 낫지만 설정이 불가능하며 비결정론적(non-deterministic)입니다.
MCP 명세 자체도 이 점을 분명히 하고 있습니다: "MCP 자체는 프로토콜 수준에서 이러한 보안 원칙을 강제할 수 없습니다." 강제하는 것은 호스트(host)의 역할이며, 현재의 호스트들은 대부분 이를 수행하지 못하고 있습니다.
격차 3: 허용 목록(allowlists)은 보안 경계가 아닙니다 — 벤더들 스스로도 그렇게 말합니다
이 부분은 모든 에이전트 사용자가 두 번은 읽어보길 권합니다. 왜냐하면 벤더들의 자체 문서에 명시되어 있기 때문입니다.
Cursor의 문구 그대로: "보안 경계가 아닙니다. 허용 목록(allowlists)과 자동 실행(autoRun) 명령은 최선의 노력을 다하는 편의 기능일 뿐입니다. 이것들은 보안 보장이 아닙니다."
Microsoft의 문구 그대로: "알려진 한계가 있는 최선의 노력을 다하는 명령 파싱(command parsing)입니다. 예를 들어, 따옴표 연결(quote concatenation)이나 셸 별칭(shell aliases)이 규칙을 우회할 수 있습니다."
이것들은 가설적인 주의 사항이 아닙니다. Cursor의 접두사 허용 목록(prefix allowlist)은 단순한 && 체이닝을 통해 실제 환경에서 우회되었습니다 (허용 목록에 cd가 있다면, cd x && terraform apply -auto-approve가 그대로 통과됩니다). CVE-2026-22708 — Cursor 2.3에서 패치됨 — 사례에서는 셸 내장 명령(shell built-ins)과 환경 변수 오염(environment-variable poisoning)이 허용 목록에 전혀 나타나지 않고 실행될 수 있었습니다.
가장 최신의 완화 조치인 Cursor의 자동 검토(Auto-review) 모드조차도 하나의 _분류 서브 에이전트(classifier subagent)_입니다. 즉, 다른 모델의 행동이 안전해 보이는지 결정하는 모델인 것입니다. 유용하긴 하지만 확률적(probabilistic)입니다. 리스크가 rm -rf인 상황에서 "보통은 잡아냅니다"라는 말은 이상한 보장입니다.
6개의 클라이언트, 6개의 모델 — 그리고 멀티 에이전트 허브도 당신을 구원하지 못합니다
만약 당신이 하나 이상의 에이전트를 실행한다면 — 그리고 현재 우리 대부분이 그러하듯 — 당신은 클라이언트마다 서로 다른 설정 형식, 서로 다른 기능, 그리고 서로 다른 실패 모드를 가진 별개의 보안 모델을 유지 관리하게 됩니다.
새로운 멀티 에이전트 허브(multi-agent hubs)가 이 문제를 해결해 주기를 바랄 수도 있습니다. 하지만 그렇지 않습니다. Devin Desktop (6월에 리브랜딩된 Windsurf)은 에이전트 클라이언트 프로토콜(Agent Client Protocol)을 통해 Codex 및 Claude Agent와 같은 제3자 에이전트를 실행하며, 해당 문서에는 다음과 같이 명확히 명시되어 있습니다: "모든 에이전트 작업은 에이전트에게 위임됩니다." 허브는 각 에이전트가 보내기로 선택한 권한 프롬프트를 그대로 표시할 뿐입니다. 보안은 여전히 이질적(heterogeneous)으로 남습니다. 허브는 UI를 통합할 뿐, 정책을 통합하는 것이 아닙니다.
한편, 당신의 설정(configs) 아래에서 지형은 요동치고 있습니다. Windsurf는 Devin Desktop이 되었고, Continue.dev는 종료 수순을 밟고 있으며, Cursor는 인수되고 있습니다. 모든 마이그레이션은 당신이 다시 작성해야 하거나, 혹은 잊어버리게 될 보안 설정(security config)입니다.
(한 가지 눈에 띄는 세부 사항: VS Code의 새로운 훅(hooks) 시스템은 Claude Code의 .claude/settings.json 형식을 읽습니다. 벤더들조차 서로 호환되지 않는 수많은 설정에 지쳐가고 있습니다.)
"그냥 훅(hooks)을 작성하세요" — 좋습니다, 하지만 대가는 이렇습니다
훅(Hooks)은 파워 유저들이 내놓는 표준적인 답변입니다. 만약 당신이 단일 클라이언트 환경에서 생활하며 bash 작성을 즐긴다면, 훅은 당신을 멀리까지 데려다줄 것입니다. Claude Code와 Cursor의 훅은 호출을 차단하고, 인자(arguments)를 재작성하며, 모델이 읽기 전에 도구(tool)의 출력을 세척(scrub)할 수 있습니다.
하지만 보안 메커니즘으로서 훅은 취약하고 파편화되어 있습니다. 첫째, 세 개의 주요 클라이언트에는 훅이 전혀 없습니다 (Codex CLI, Claude Desktop, Devin Desktop). 둘째, 존재하는 훅들도 일관성이 없습니다. VS Code의 훅은 아무것도 재작성할 수 없습니다.
가장 큰 위험 신호는 무엇일까요? Cursor의 훅은 기본적으로 '페일 오픈(fail open)' 방식으로 작동합니다. 만약 당신의 bash 스크립트가 충돌하거나, 타임아웃이 발생하거나, 구문 오류(syntax error)가 발생하면, 위험한 동작이 그대로 실행됩니다. 보안에서 '페일 오픈'되는 방화벽은 방화벽이 아니라, 그저 권고 사항일 뿐입니다. 그리고 설령 완벽한 스크립트를 작성한다 하더라도, 당신은 프로젝트별로, 클라이언트별로 이를 영원히 유지 관리해야 합니다.
인라인 프록시(inline proxy)가 다르게 하는 것
공지: 저는 제 개인적인 갈증을 해소하기 위해 아래 도구를 직접 만들었습니다. 이 점을 염두에 두고 이 섹션을 읽어주시기 바랍니다.
방금 언급한 격차들은 모두 동일한 구조적 결함을 공유합니다. 바로 강제 집행(enforcement)이 클라이언트 내부에 존재한다는 점입니다. 이는 보안이 각 개별 클라이언트의 구현만큼만 강력하고 일관적일 수 있음을 의미합니다.
저는 다섯 개의 서로 다른 파편화된 설정을 유지 관리하는 것에 지쳤고, 그래서 강제 집행의 위치를 클라이언트 아래로, 즉 MCP 연결 자체로 직접 옮기기로 결정했습니다.
그것이 제가 MCP-Shield를 만든 이유입니다. 이것은 모든 MCP 클라이언트와 서버 사이의 JSON-RPC 와이어(wire) 상에 위치하는 인라인 로컬 프록시(local proxy)입니다. 철학은 간단합니다:
- 모든 것을 통제하는 단일 정책 (One policy to rule them all). 규칙을 한 번만 작성하면 Claude Code, Cursor, Codex, VS Code 또는 MCP를 사용하는 그 어떤 도구에서 호출이 오더라도 즉시 적용됩니다.
- MCP 도구 호출에 대한 인자 수준의 규칙 (Argument-level rules on MCP tool calls) — 6개의 클라이언트 중 그 어느 것도 네이티브하게 해결하지 못한 명백한 빈틈입니다 (격차 1).
- 출력 데이터 정화 (Output sanitization) — 오염된 데이터가 모델의 컨텍스트 윈도우 (context window)에 도달하기 전에 처리합니다 (격차 2).
- 결정론적이고 실패 시 차단하는 강제 적용 (Deterministic, fail-closed enforcement). 확률적 분류기 (probabilistic classifiers)가 아닌 엄격한 규칙을 사용합니다. 규칙에 어긋나면 접근을 거부합니다 (격차 3).
- 실시간 로컬 대시보드 (A live local dashboard) 를 통해 실행 전 대기 중인 호출을 즉석에서 검토, 승인, 거부하거나 심지어 _수정_할 수 있습니다.
- 로우 와이어 (raw wire)를 검사하기 때문에, 네이티브 훅 (native hooks)이 구조적으로 아예 볼 수 없는 속임수(중복 키 파서 차이(duplicate-key parser differentials) 및 배치 스머글링(batch smuggling) 등)를 잡아냅니다.

목표는 마찰 없는 사용(zero friction)이었습니다. 기존 클라이언트 설정을 건드릴 필요 없이, 설치 프로그램이 와이어링(wiring)을 처리합니다:
npm install -g @jrooig/mcpshield
mcp-shield install
이것이 수행하지 않는 것
솔직하게 말씀드리겠습니다. MCP-Shield는 정밀한 메스(scalpel)이지, 만능 해결책(magic bullet)이 아닙니다. 이 도구는 오직 MCP 트래픽만을 가로챕니다. 만약 에이전트가 내장된 터미널이나 네이티브 파일 편집 기능을 사용한다면, MCP-Shield는 이를 감지할 수 없습니다. (그것이 바로 네이티브 OS 샌드박스(OS sandboxes)가 존재하는 이유입니다. 두 가지를 모두 사용하세요.)
사전 구축된 규칙들은 가장 흔한 파괴적인 패턴들을 다루지만, 모든 것을 다 잡아내는 것은 아닙니다. 사용자는 자신의 워크플로우에 맞춰 규칙을 읽고 확장해야 합니다. 그리고 당연하게도, 세상의 어떤 소프트웨어도 프롬프트를 읽지 않고 맹목적으로 "승인(Approve)"을 클릭하는 인간의 실수를 고칠 수는 없습니다. 이것은 방어 심층 (defense-in-depth)의 추가적인 계층이지, 사고를 멈춰도 되는 자유 이용권이 아닙니다.
이것이 우리를 어디로 이끄는가
공을 돌리자면, 벤더(vendors)들도 이 문제를 진지하게 받아들이고 있으며 실질적인 제동 장치를 구축하고 있습니다. VS Code의 기본 활성화(default-on) 커널 샌드박스(kernel sandbox)는 출시된 지 겨우 2주밖에 되지 않았지만, 이는 거대한 진전입니다.
하지만 아키텍처(architecture)가 바뀌기 전까지 이 세 가지 격차는 구조적인 상태로 남아있을 것입니다. 강제 적용(enforcement)이 클라이언트별(per-client)로 처리되는 한, 우리는 논리적 맥락을 고려하지 않는 MCP 승인(argument-blind MCP approvals), 필터링되지 않은 도구 출력(unfiltered tool outputs), 그리고 스스로 보안 경계(security boundaries)가 아님을 명시적으로 인정하는 N개의 서로 다른 설정(configs)에 갇혀 있게 됩니다.
에이전트(agents)는 이미 오래전에 클라이언트를 가로질러 확장되었습니다. 공격 또한 이제 클라이언트를 가로질러 발생하고 있습니다. 이제 우리의 보안 계층(security layer) 역시 클라이언트를 가로질러(cross-client) 적용되어야 할 때입니다.
코드의 허점을 찾고 싶거나 직접 사용해보고 싶다면, MCP-Shield는 오픈 소스 (MIT)입니다: github.com/jaumerohi2007-cell/mcp-shield · mcp-shield.dev
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기