당신의 코딩 에이전트 승인 대화창은 당신에게 거짓말을 하고 있습니다
요약
Wiz Research가 Amazon Q Developer, Claude Code, Cursor 등 주요 AI 코딩 어시스턴트에서 발견된 'GhostApproval' 심볼릭 링크 취약점을 공개했습니다. 이 버그는 에이전트가 승인 대화창에 표시된 파일명과 실제 수정하는 파일명이 다를 수 있는 점을 악용하여 사용자의 SSH 키 등을 탈취할 수 있습니다.
핵심 포인트
- 심볼릭 링크를 이용해 승인 대화창의 파일명과 실제 대상 파일명을 다르게 표시 가능
- 에이전트가 파일 시스템의 실제 경로를 해석하지 못하는 신뢰 경계 간극 존재
- Amazon, Google, Cursor는 패치를 완료했으나 업체별 대응 방식은 상이함
- Cursor에서 발견된 프롬프트 주입 기반 RCE 취약점(DuneSlide) 사례도 언급됨
7월 8일, Wiz Research는 Amazon Q Developer, Claude Code, Augment, Cursor, Google Antigravity, 그리고 Windsurf 등 6개의 주요 AI 코딩 어시스턴트(AI coding assistants)를 동시에 타격한 심볼릭 링크(symlink) 결함인 GhostApproval을 공개했습니다. 이 버그는 모욕적일 정도로 단순하며, 바로 그 점 때문에 작동했습니다.
어떤 저장소(repo)가 project_settings.json이라는 이름의 파일을 배포합니다. 이 파일은 실제로는 당신의 SSH 키를 가리키는 심볼릭 링크(symlink)입니다. 당신이 에이전트에게 "워크스페이스를 설정해줘(set up the workspace)"라고 요청합니다. 에이전트는 링크를 해석(resolve)하여 실제 대상에 내용을 쓰고, 당신에게 project_settings.json이라고 표시된 승인 대화창(approval dialog)을 보여줍니다. 왜냐하면 그것이 에이전트가 전달받은 이름이지, 에이전트가 곧 건드릴 실제 파일 이름이 아니기 때문입니다. 당신은 승인을 클릭합니다. 당신은 자신도 모르는 사이에 ~/.ssh/id_rsa에 대한 쓰기 권한을 허용해 버린 것입니다.
이 공개 내용에서 세 가지 사항이 눈에 띕니다.
-
대화창은 설계된 대로 정확히 작동했습니다. 대화창은 도구 호출(tool call)이 실행된 경로를 보여줄 뿐, 심볼릭 링크(symlink)를 따라간 후 파일 시스템(filesystem)이 실제로 해석하는 경로를 보여주지 않습니다. 에이전트가 하고 있다고 말하는 것과 파일 시스템이 실제로 수행하는 것 사이의 이 간극은 수십 년 된 유형의 버그입니다. TOCTOU(Time-of-Check to Time-of-Use) 및 심볼릭 링크(symlink) 공격은 LLM보다 30년 앞서 존재했으며, 과거의 교훈을 아무도 에이전트 기반 코딩(agentic coding)으로 가져오지 않았기 때문에 이 문제는 그대로 에이전트 코딩 환경으로 걸어 들어왔습니다.
-
공급업체들은 이것이 취약점인지 여부에 대해 의견이 갈렸습니다. Amazon, Google, Cursor는 수정 사항을 배포했습니다. Augment와 Windsurf는 침묵했습니다. Anthropic은 Claude Code의 동작이 결함이라는 사실 자체를 반박하며, 디렉토리를 신뢰하고 편집을 승인한 사용자가 그 결정에 대한 책임을 진다고 주장했습니다. 추상적으로는 방어 가능할지 모르나, 실제로는 쓸모가 없습니다. "워크스페이스를 설정해줘"라는 요청을 검토하는 사람 중 누구도 '예'를 클릭하기 전에 머릿속으로 심볼릭 링크(symlink)를 해석하지 않습니다. 인간이 공격자보다 더 똑똑하게 생각할 것을 요구하는 동의는, 동의라는 이름으로 포장된 책임 전가에 불과합니다.
같은 주에, Cursor는 DuneSlide를 패치했습니다. 이는 두 건의 CVSS 9.8 제로 클릭 RCE (원격 코드 실행, Remote Code Execution) 취약점으로, MCP (Model Context Protocol) 응답이나 검색 결과에 포함된 프롬프트 주입 (Prompt Injection) 명령어가 샌드박스 (Sandbox)를 완전히 탈출하여 승인 절차 없이 실행되는 문제였습니다. GhostApproval과 DuneSlide는 서로 다른 두 가지 방식으로 신뢰 경계 (Trust Boundary)를 잘못된 곳에 설정했습니다. 하나는 인간이 시간 압박 속에서 대화창을 정확히 읽는 것에 의존하며, 다른 하나는 인간을 완전히 건너뜁니다.
행위별 승인 (Per-action approval)은 결코 아키텍처 (Architecture)가 아닙니다. 그것은 에이전트가 누구보다 빠르게 생성하는 결정에 대해, 사람이 매번 올바른 보안 판단을 내리도록 요구하는 임시방편일 뿐입니다. GhostApproval은 에이전트와 당신의 SSH 키 사이를 가로막는 유일한 장벽이 '당신이 파일 이름을 알아챘는가'뿐일 때 발생하는 현상입니다.
실질적인 해결책은 행위가 발생할 때마다 누군가에게 심판을 맡기는 것이 아니라, 에이전트가 실행되기 전에 접근할 수 있는 범위를 제한 (Scoping)하는 것입니다. 특정 작업에 대해 어떤 경로, 어떤 작업, 어떤 디렉토리가 허용 범위 내에 있는지를 열거하는 명세 (Spec)는 "인간이 이것을 잡아냈는가"를 "이것이 애초에 허용된 동작이었는가"로 바꿉니다. 에이전트가 애초에 /src 외부에는 쓰기 권한이 부여되지 않았다면, 심볼릭 링크 공격 (Symlink attack)을 인간이 더 똑똑하게 생각해서 막아낼 필요도 없습니다. 폭발 반경 (Blast radius)을 사전에 정의할 수 있도록 명세 (Specs)를 작성하세요. 아무도 확인할 시간이 없는 대화창에 그 책임을 외주 주는 일을 멈추십시오.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기