
신뢰할 수 없는 코드 실행: 왜 스킬 허용 목록(Skill Allowlist)은 최소한의 방어선인가
요약
ClawHavoc 사례를 통해 AI 에이전트의 악성 스킬 공격 위험성을 분석합니다. 단순한 허용 목록(Allowlist) 방식은 스킬이 에이전트의 권한을 그대로 상속받는 구조적 결함을 해결할 수 없음을 지적합니다.
핵심 포인트
- ClawHavoc: 악성 스킬을 이용한 에이전트 권한 탈취 공격 사례
- 허용 목록의 한계: 신뢰된 스킬이 침해될 경우 에이전트 전체가 위험함
- 권한 상속 문제: 스킬이 설치되면 에이전트의 모든 권한을 갖게 되는 구조적 결함
- 보안 아키텍처의 필요성: 단순 검토를 넘어선 근본적인 권한 분리 설계 필요
2026년 초, 공격자들은 OpenClaw의 커뮤니티 스킬 레지스트리인 ClawHub에 1,100개 이상의 악성 스킬을 업로드했습니다. 많은 스킬이 트레이딩 봇, 생산성 유틸리티 또는 코딩 도우미로 위장했습니다. 그중 여러 개가 최다 다운로드 목록에 올랐습니다. hightower6eu라는 핸들을 사용하는 한 공격자는 단일 캠페인에서 거의 동일한 악성 스킬 수십 개를 업로드했습니다. Hacker News의 기사는 이를 ClawHavoc라고 명명했습니다. IBM은 이를 자신들이 정의한 6가지 에이전트 위험 중 첫 번째인 **신뢰할 수 없는 코드 실행 (untrusted code execution)**의 전형적인 사례로 인용했습니다.
흥미로운 질문은 "이런 일이 어떻게 일어났는가"가 아닙니다. "ClawHavoc가 일어날 법한 일이 아니라, 기계적으로 아예 불가능하게 만들려면 개인용 AI 에이전트의 아키텍처(architecture)가 어떻게 구성되어야 하는가?"입니다. 바로 이 지점에서 허용 목록 (allowlists)만으로는 충분하지 않게 됩니다.
증거 (The receipts)
OpenClaw의 스킬 모델은 모든 현대적인 에이전트 스킬 모델과 유사합니다. 매니페스트 (manifest, OpenClaw의 경우 SOUL.md, 다른 대부분의 경우 SKILL.md), 일부 코드 또는 지침 본문, 그리고 설치를 위한 마켓플레이스로 구성됩니다. 에이전트는 스킬을 로드하고, 스킬은 에이전트가 사용할 수 있는 기능의 일부가 되며, 이제 에이전트의 프롬프트 (prompts)가 이를 호출할 수 있습니다. 이것이 설계 방식입니다.
이러한 설계의 경제성은 공격자에게 압도적으로 유리합니다. 스킬을 게시하는 데는 몇 분밖에 걸리지 않습니다. 정보 탈취 도구 (info-stealer)를 설치하고, ~/.ssh를 유출하며, 호스트에 지속적인 에이전트를 심는 등 제 역할을 수행하는 악성 스킬은 첫 실행 시 바로 작업을 완료합니다. 누군가 이를 보고할 때쯤이면, 이미 수백 대의 개발자 컴퓨터에서 몇 시간 동안 실행된 상태가 됩니다.
이 상황에서 일반적으로 선택하는 방어책은 서명(signing, 게시자 키)과 허용 목록(allowlists, 선별된 세트에서만 설치)입니다. 두 방법 모두 도움이 되지만, 어느 하나만으로는 충분하지 않습니다. 게시자 키는 도용될 수 있으며, 특히 게시 장벽이 낮은 커뮤니티 스킬의 경우 더욱 그렇습니다. 허용 목록은 공격 표면(surface)을 좁혀주지만, 허용된 스킬이 일단 로드된 이후에 무엇을 할 수 있는지는 바꾸지 못합니다. 만약 당신의 모델이 "신뢰할 수 있는 스킬은 에이전트의 모든 권한을 갖는다"라고 정의되어 있다면, 신뢰할 수 있는 스킬이 침해되는 날이 바로 에이전트가 침해되는 날입니다.
이것이 바로 IBM이 명명한 격차(gap)입니다. X-Force 보고서에 따르면 다음과 같습니다: "많은 문제들이 명령 실행(command execution), 유출된 평문 API 키 및 자격 증명(credentials)과 연관되어 있으며, 이는 공격자가 간접 프롬프트 주입(indirect prompt injection), 악성 스킬(malicious skills) 또는 보안되지 않은 엔드포인트(unsecured endpoints)를 통해 훔칠 수 있습니다." 악성 스킬 벡터와 자격 증명 유출 벡터는 두 가지 모습의 동일한 문제, 즉 "신뢰해서는 안 될 코드가 신뢰할 수 있는 코드만이 수행해야 할 작업을 수행하게 되었다"는 점입니다.
아키텍처의 교훈
이런 종류의 사고가 발생했을 때 본능적으로 취하는 조치는 마켓플레이스를 봉쇄하는 것입니다. 업로드물을 더 엄격하게 검토하고, 다운로드 수가 높은 스킬을 조사하며, 악성 행위자를 더 빠르게 차단하는 것입니다. 이 모든 것은 옳은 방향이며, OpenClaw도 이를 많이 수행해 왔습니다.
하지만 이것이 해결하지 못하는 것은 아키텍처의 형태입니다. 즉, 스킬은 일단 설치되면 에이전트의 권한을 상속받는다는 점입니다. 에이전트가 파일 시스템 접근 권한을 가지고 있다면? 스킬도 파일 시스템 접근 권한을 가집니다. 에이전트의 환경 변수에 Anthropic API 키가 있다면? 스킬도 Anthropic API 키를 가집니다. 에이전트가 shell.run을 호출할 수 있다면? 스킬도 원하는 어떤 인자(argument)를 사용하여 shell.run을 호출할 수 있습니다.
그러한 형태는 대부분의 에이전트 스택(agent stacks)에 내장되어 있습니다. 스킬을 설치한다는 것은 실제로 그 스킬에게 에이전트가 이미 보유한 모든 기능의 합집합(union)을 부여하는 행위입니다. 암묵적인 신뢰 경계(trust boundary)는 "이것이 허용 목록에 있는 소스에서 왔는가"이며, 일단 이 검사를 통과하면 더 이상의 게이트(gate)는 작동하지 않습니다. 런타임(runtime)을 변경하지 않고서는 "이 스킬은 X는 할 수 있어야 하지만 Y는 할 수 없어야 한다"라고 명시할 수 없습니다.
더 깊은 질문은 에이전트가 권한(capability)을 **설치 경계(install boundary)**가 아닌 **스킬 호출 경계(skill-call boundary)**에서 강제해야 하는가 하는 점입니다. 설치 경계는 코드가 어디에서 왔는지를 확인합니다. 호출 경계는 이 특정 호출이 사용자가 해당 스킬에 허용한 것인지를 확인합니다. 전자는 공급망 위생(supply-chain hygiene)에 해당하며, 후자는 최소 권한 원칙(least-privilege)에 해당합니다.
Ardur의 처리 방식
Ardur에서 스킬은 에이전트의 권한을 절대 상속받지 않습니다. 스킬이 수행하는 모든 도구 호출(tool call) — 파일 읽기, HTTP 엔드포인트 호출, 셸 명령 실행, 모델 호출 등 — 은 호출이 실행되기 전 런타임(runtime)이 확인하는 **캡-토큰(cap-token)**을 반드시 동반해야 합니다. 이 캡-토큰은 Biscuit 형식으로 구성되며, Ed25519로 서명되고, 특정 리소스에 대한 특정 동사(verb)로 범위가 제한(scoped)되어 있으며, 스킬이 권한을 좁힐 수는 있지만 절대 넓힐 수는 없도록 감쇄(attenuable) 가능합니다.
구체적으로 살펴보면: ~/reading에 있는 논문을 요약한다고 명시된 스킬은 설치 시점에 실질적으로 ~/reading/**에 대한 file.read 권한만을 가진 캡-토큰을 발급받습니다. 만약 해당 스킬이 악의적으로 변하여 ~/.ssh/id_rsa를 읽으려 시도한다면, 런타임 경계에서 캡-토큰 검증이 실패합니다. 도구 호출은 거부(Denied)를 반환합니다. 에이전트가 거절할 만큼 똑똑할 필요조차 없었습니다. 와이어 포맷(wire format) 자체가 거절했기 때문입니다.
이 과정은 FusedRuntime 파이프라인 내에서 매 턴(turn)의 첫 번째 단계로 포함됩니다. 캡-토큰 검증이 1단계입니다. Cedar 정책(더 풍부한 정책 언어를 통한 허용(Allow) / 거부(Deny) / 미결정(Indeterminate))이 2단계입니다. 비용 게이트(Cost gate)가 3단계입니다. 이 중 어느 하나라도 실패하면, 모델이 호출되기도 전에 해당 턴은 단락(short-circuit)됩니다. 어떤 스킬도 이러한 단계들을 통과하여 도구 호출을 몰래 수행할 수 없습니다. 왜냐하면 이 단계들은 설치 시점의 스킬이 아니라, 모든 도구 호출 시점에 실행되기 때문입니다.
여기서 모델의 정체성(identity) 또한 중요합니다. 캡-토큰 (Cap-token)은 호출자의 주장이 아니라 검증된 토큰으로부터 그 주체(principal)를 도출합니다. 악의적인 스킬은 다른 스킬이라고 주장하거나, 사용자라고 주장하거나, 시스템이라고 주장할 수 있습니다. 런타임 (runtime)은 상관하지 않습니다. 주체는 실제로 감쇄되지 않은 부모 토큰 (unattenuated parent token)을 보유하고 있는 서명된 당사자이며, 그 당사자가 애초에 해당 스킬을 설치한 쪽입니다.
Cedar 정책 레이어 (policy layer)는 캡-토큰만으로는 전달할 수 없는 컨텍스트 (context)에 의존하는 규칙을 표현할 수 있게 해줍니다. "이 스킬은 http.fetch 호출을 할 수 있지만, 오전 9시에서 오후 5시 사이에만 가능하다.", "이 스킬은 모델을 호출할 수 있지만, claude-opus가 아닌 claude-haiku로만 호출할 수 있다."와 같은 규칙들입니다. 이러한 정책들은 기본 거부 (deny-by-default) 방식입니다. 즉, 결정 불가능 (Indeterminate) 결과는 거부 (Deny)로 처리되며, 이는 정책이 불확실할 때 취할 수 있는 유일하게 안전한 해석입니다.
AI 스킬은 당신이 작성하지 않은 코드가 당신이 허용하지 않을 권한을 가지고 실행되는 것입니다.
우리가 솔직해져야 할 부분
Ardur의 스킬 모델이 완벽하다고 주장한다면 그것은 기만일 것입니다. 두 가지 특정 측면에서 완벽하지 않습니다.
첫째, 캡-토큰 모델은 악의적인 스킬이 잘못된 도구 호출을 '실행'하는 것만을 방어합니다. 악의적인 스킬이 에이전트의 추론을 하이재킹(hijack)하는 '프롬프트 콘텐츠를 제공'하는 것까지는 방어하지 못합니다. 이는 간접 프롬프트 인젝션 (indirect prompt injection) 클래스에 해당하며, 이 시리즈의 다음 주제이자 cap-token 크레이트 (crate)가 아닌 injection-defense 크레이트에 포함되어 있습니다.
둘째, Ardur의 두 가지 공개된 내구성 티켓(durability tickets) — ARD-17 (단일 단계 저널 커밋) 및 ARD-19 (하이브리드 메모리에 아직 연결되지 않은 회상 기능) — 는 충돌 직전에 단 한 번의 잘못된 동작을 수행한 오염된 스킬이 그 영수증을 고아(orphan)로 만들 수 있음을 의미합니다. 우리는 이 두 가지를 RUN.md에서 추적하고 있습니다. 이것들이 바로 우리가 여전히 Ardur를 개발 피델리티 (dev fidelity) 단계라고 부르는 이유입니다.
ClawHavoc가 보여주는 문제 유형인 "허용 목록에 포함된 스킬이 에이전트가 할 수 있는 모든 일을 수행할 수 있다"는 문제는 Ardur가 취약한 유형이 아닙니다. 왜냐하면 에이전트 자체가 상속받을 수 있는 권한을 마구잡이로 가지고 있지 않기 때문입니다. 에이전트는 캡 토큰 (cap-tokens)을 가집니다. 스킬은 더 좁은 범위의 캡 토큰 (cap-tokens)을 가집니다. 그 무엇도 "모든 것"을 가지고 있지는 않습니다.
시사점 (The takeaway)
만약 당신이 개인용 AI 에이전트를 실행 중이고, 당신의 스킬 보안 모델이 "공식 레지스트리에서 설치하기"라면, 당신은 레지스트리의 검증 파이프라인 (vetting pipeline)이 공격자의 반복 주기 (attacker iteration)보다 빠르다는 점에 의존하고 있는 것입니다. ClawHavoc는 공격자의 반복 주기를 늦추는 것이 매우 어렵다는 점을 시사합니다.
우리가 전환해야 할 가치 있는 변화는 공급망 위생 (supply-chain hygiene, 여전히 수행해야 할 작업)에서 호출 경계에서의 최소 권한 (least-privilege at the call boundary, 이 또한 반드시 수행해야 할 작업)으로의 이동입니다. 전자는 코드가 어디에서 왔는지를 묻습니다. 후자는 코드가 실행된 후 무엇을 할 수 있도록 허용되는지를 묻습니다. 후자는 바닥(최소한의 방어선)이며, 전자는 그 바닥 위에 구축하는 것입니다.
만약 당신의 스택이 "이 도구 호출이 어떤 캡 토큰 (cap-token)을 타고 실행되었는가?"라는 질문에 답할 수 없다면, 그것이 바로 보안의 공백입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기