
- 원문: arXiv 2609.28586
- 저자: Jinqian Zhang, Haojun Xia, Shujiang Wu, Jingkun Yue, Xia Zhang, Zhangpei Cheng, Bibo Tu
- 공개일: 2026-09-25
- 분야: Agent Authorization, Approval Records, Coding Agents, MCP
- Tags: Authorization, Approval, CodingAgent, MCP, TransitiveEffects
본 글은 원 논문의 주요 기술적 내용을 이해하기 쉽게 요약·정리한 글입니다. 자세한 내용은 상단의 원문 링크를 참고하세요.
한눈에 보기
이 논문은 coding agent가 사용자에게 승인받은 command나 tool call 자체는 정확히 기록해도, 그 호출이 내부적으로 실행한 lifecycle hook, build script, file write, network access 같은 transitive effect가 승인 기록에서 사라지는 현상을 approval laundering이라고 정의합니다. 문제는 거짓 command name이 아니라 invocation identity와 실제 authority closure 사이의 정보 손실입니다.
111개의 고정 approval-object/trace pair에서 effect가 빠진 record는 explicit field만 볼 때 40개, generic command semantics를 추가하면 17개, decision-time metadata를 사후 적용하면 13개였습니다. 별도의 fixed-SHA real-project execution 11건에서는 10개, 2개, 0개로 감소했습니다. pre-authorization metadata parser는 holdout 17건에서 macro recall 0.926, precision 0.941을 기록했고 residual effect instance를 10개에서 3개로 줄였습니다.
연구 배경
coding agent의 approval UI는 보통 pnpm install, docker build, MCP tools/call처럼 entry invocation을 보여 줍니다. 그러나 package manager는 postinstall을 실행하고, Dockerfile은 여러 build step을 수행하며, MCP server는 외부 network를 사용할 수 있습니다. 사용자가 승인한 문자열과 실제 workflow의 effect set은 같지 않습니다.
논문은 승인 record가 truthful하더라도 effect-complete하지 않을 수 있다고 지적합니다. 효과가 생긴 뒤 trace를 분석하는 것만으로는 승인 당시 사용자가 무엇을 알았는지 복원할 수 없으므로, prediction과 provenance를 decision 전에 record에 bind해야 합니다.
공격 모델 / 전제 조건
공격자는 project metadata, dependency, build script, hook, MCP configuration처럼 승인된 invocation이 읽는 expansion source를 통제하거나 악용합니다. 사용자는 visible command 또는 named tool call을 승인하지만, transitive workflow 안의 file, network, container, environment, process, MCP effect를 개별적으로 보지 못합니다.
논문은 prompt-visible field, command semantics, decision-time metadata를 구분합니다. attacker가 approval UI 자체를 위조할 필요는 없고, 동일한 visible field를 가진 두 execution이 서로 다른 policy decision을 요구하게 만들면 record-only policy는 완전한 판정을 보장할 수 없습니다.
비판적 검토 / 아쉬운 점
가장 큰 한계는 six-effect vocabulary가 운영상 유용하지만 coarse하다는 점입니다. network effect가 있다는 사실만으로 destination, method, credential scope, data volume을 구분하지 못하고 file effect도 path와 integrity impact를 설명하지 못합니다. 실제 authorization에는 effect class 아래의 resource identity와 constraint가 더 필요합니다.
두 번째로 headline 111 record 중 metadata-aware residual 13개가 모두 harness/parser fixture stratum에 집중됩니다. fixed-SHA 11건에서는 0개가 되었지만 표본이 작고 8개 selected case에 불과합니다. 더 다양한 monorepo, dynamic script generation, remote dependency resolution, Windows-specific workflow에서 검증이 필요합니다.
세 번째로 effect-bound policy의 operating point가 보수적입니다. prespecified 18 case 중 17건에서 ASK를 냈고, 실제 effect가 추가되지 않은 target-executed case도 9건이었습니다. 자동 승인 없이 안전하게 연결했다는 장점은 있지만 approval fatigue를 해결한 것은 아닙니다.
네 번째로 parser가 inspectable local metadata를 전제로 합니다. generated script, encrypted configuration, remote mutable registry, runtime-discovered plugin처럼 decision-time에 source-backed prediction이 불가능한 workflow에서는 unknown 또는 deny로 처리할 정책이 추가로 필요합니다.
핵심 Root Cause
구조적 원인은 authorization object가 entry invocation을 identity unit으로 삼는 반면, 실제 authority는 workflow closure를 따라 확장된다는 점입니다. approval record가 process effect만 나타내도 실행은 file, network, environment, container, MCP capability까지 사용할 수 있습니다.
깨진 보안 불변조건은 “승인 시점의 durable record가 허용된 workflow가 도달 가능한 policy-relevant effect를 모두 표현해야 한다”입니다. 실행 후 trace에 effect가 남더라도 decision context에 사전 bind되지 않았다면 사용자의 informed authorization은 성립하지 않습니다.
핵심 공격 원리
논문은 effect vocabulary를 Process, File, Environment, Network, Container, MCP의 여섯 class로 구성합니다. sealed record가 표현한 집합과 observed trace의 effect set 차이를 residual로 정의하고, residual이 비어 있지 않으면 approval laundering witness로 봅니다.
Vite 사례에서 pnpm install --frozen-lockfile record는 process만 표현했지만 postinstall과 node_modules/.modules.yaml write가 발생했습니다. MCP 사례에서는 named documentation tool call이 MCP capability를 표현했지만 .mcp.json의 transport를 통해 network authority도 사용했습니다.
공격 흐름
- agent가 command 또는 tool call에 대한 approval을 요청합니다.
- UI와 durable record는 prompt-visible invocation을 seal합니다.
- package metadata, build script, task file, hook, MCP config가 workflow를 확장합니다.
- 실행은 record에 없는 file·network·environment·container effect를 수행합니다.
- 사후 trace에는 effect가 남을 수 있지만 authorization 당시에는 표시되지 않았습니다.
- 공격자는 이 차이를 이용해 승인된 entry point 안에서 더 넓은 authority를 행사합니다.
성공 조건 / 실패 조건
성공하려면 approved invocation이 project 또는 server metadata를 따라 transitive behavior를 실행하고, approval record가 해당 effect를 표현하지 않아야 합니다. omitted effect가 policy-relevant하고 attacker가 expansion source를 통제하거나 선택할 수 있을수록 위험이 커집니다.
실패 조건은 approval 전에 workflow source를 freeze하고 effect prediction, source hash, provenance를 invocation과 함께 bind하는 것입니다. runtime sandbox가 예측된 effect 범위를 강제하고, 실행 뒤 transcript와 realized-effect hash를 append하면 사전 disclosure와 사후 audit가 함께 성립합니다.
연구진의 실험 환경
benchmark는 npm lifecycle, PEP 517, Cargo build script, Docker build, Git hook, VS Code task, MCP server, nested shell, unittest import의 9개 mechanism을 다룹니다. 149개 attempt/run snapshot 중 success 139개를 정리하고 latest-success rule로 111개 canonical agent–task record를 만들었습니다.
fixed-SHA 실험은 webpack, Vite, pip, Flask, ripgrep, VS Code, awesome-compose, modelcontextprotocol/servers 등 8개 selected case의 evidence-complete execution 11건입니다. frontend는 Claude Code 2.1.193, Codex CLI 0.142.0, GitHub Copilot CLI 1.0.65, OpenCode 1.1.25, Qwen Code 0.19.2를 포함합니다.
prospective Confirmatory B는 이전에 보지 않은 fixed-SHA repository 18개에서 mechanism별 positive와 control을 prespecify했습니다. 17건이 target execution에 도달했고 13건 성공, 4건은 effect evidence 이후 command failure, 1건은 setup failure였습니다.
주요 실험 결과
동일한 111 record에서 residual count는 explicit 40개, command-aware 17개, metadata-aware 13개였습니다. mechanism별 metadata residual은 IDE task 3개, MCP 4개, npm 2개, nested shell 2개, test-runner import 2개였고 나머지는 0개였습니다.
fixed-SHA 11 execution은 explicit 10개, command 2개, metadata 0개 residual이었습니다. Vite의 Process→Process·File과 MCP의 MCP→MCP·Network exact mapping은 세 product frontend의 네 run에서 반복됐습니다.
Confirmatory B 17건에서 metadata prediction은 macro recall 0.926, precision 0.941, exact set 13/17이었습니다. command-only baseline은 recall 0.770, precision 0.941, exact set 9/17이었습니다. 109개 raw artifact를 independent verifier가 hash-check하고 effect set을 재구성했으며 mismatch는 없었습니다.
effect-bound record의 disclosed-effect coverage는 0.755에서 0.922로 올랐고 residual effect instance는 10개에서 3개로 감소했습니다. parser의 worst same-process P95는 12.3 ms, Python startup을 포함한 fresh-process maximum P95는 168.2 ms였습니다.
실제 발견된 취약점 / 사례
Vite fixed commit 64dfee12에서 approved pnpm install은 simple-git-hooks postinstall과 workspace file write를 실행했습니다. command semantics는 file을 예측했지만 실제 run에서 발생하지 않은 network도 보수적으로 예측했습니다.
modelcontextprotocol/servers commit 7b1170d1의 documentation tool call은 GitHub Copilot CLI와 Qwen Code에서 named MCP action과 concrete remote response를 만들었습니다. generic tool-call semantics는 MCP만 표현했고 123-byte .mcp.json metadata가 network transport를 밝혔습니다.
논문은 특정 제품의 CVE를 제시하지 않습니다. 이는 UI spoofing이 아니라 여러 정상 developer workflow에서 반복되는 authorization-record design failure입니다.
저자 주장 vs 실제 증명 범위
동일 policy-visible field가 다른 effect-specific decision을 요구하면 record-only policy가 deterministic이든 randomized이든 둘을 모두 보장할 수 없다는 정보 한계는 formal model로 뒷받침됩니다. 실제 workflow에서 representation ladder가 residual을 줄인다는 주장도 fixed pair와 fixed-SHA execution으로 검증됐습니다.
다만 metadata parser가 모든 real-world workflow closure를 완전히 예측한다고 증명한 것은 아닙니다. holdout에서도 file effect 3건을 놓쳤고 process와 MCP effect를 각 1건 과대 예측했습니다. effect-bound record는 위험을 줄이는 proposal이지 완전한 policy enforcement가 아닙니다.
기존 공격 / 기존 점검 방식과의 차이
일반 confused deputy나 approval–execution binding은 승인된 action이 다른 action으로 바뀌었는지를 봅니다. approval laundering은 entry invocation이 정확해도 그 invocation의 transitive effect closure가 record에서 누락되는지를 봅니다.
command allowlist는 문자열이나 tool name을 기준으로 하므로 metadata-selected behavior를 놓칩니다. 사후 audit log는 실제 effect를 보여 줄 수 있지만 승인 당시 disclosure를 소급해 만들 수 없습니다. effect-bound record는 decision 전에 prediction과 provenance를 seal한다는 점이 다릅니다.
연구의 한계와 주의해서 볼 부분
effect set은 실행마다 달라질 수 있고 cache, platform, dependency registry 상태가 결과에 영향을 줍니다. 논문은 fixed SHA와 frozen parser·prediction으로 leakage를 줄였지만 mutable external source까지 완전히 고정한 것은 아닙니다.
prediction quality와 policy quality는 별개입니다. 올바르게 network effect를 예측해도 어떤 domain과 credential을 허용할지 결정하는 logic이 없으면 authorization은 여전히 거칠게 남습니다. 또한 ASK 17/18은 usability tradeoff를 크게 보여 줍니다.
공개 PoC / Exploit / Tool / Artifact 분석
논문은 Approval-to-Action benchmark, frozen prediction bundle, raw artifact와 verifier를 설명하고 중국 Science Data Bank의 공식 dataset page가 검색됩니다. 그러나 arXiv 본문에서 논문 전용 공식 GitHub 저장소를 확인하지 못했습니다.
따라서 현재 공개 GitHub ZIP 보관 대상은 없습니다. dataset page는 Agent Approval Laundering dataset이며, 공개 접근 조건과 전체 bundle 구조는 별도 검증이 필요합니다.
레드팀 / 모의해킹에서 어떻게 활용할까
승인 UI를 테스트할 때 command string만 보지 말고 package script, build backend, Dockerfile, task definition, hook, MCP transport가 만드는 closure를 수집해야 합니다. synthetic repository에 harmless marker file과 controlled local endpoint를 두고 approval record가 이를 사전에 표현하는지 비교합니다.
검증 기준은 visible invocation, predicted effect, source hash, final decision, realized effect가 하나의 transaction으로 연결되는지입니다. 외부 network나 실제 credential 사용이 발생하면 즉시 중단하고 sandbox 안의 canary resource로 제한합니다.
실제 점검 시 추가할 체크리스트
- 승인 화면에 command·tool name과 predicted effect를 별도 field로 표시합니다.
- package.json, pyproject.toml, Cargo.toml, Dockerfile, task file, hook, MCP config를 decision 전에 해석합니다.
- expansion source의 content hash와 parser version을 record에 bind합니다.
- File과 Network를 path·destination·credential scope까지 세분화합니다.
- unknown dynamic behavior는 자동 승인하지 않고 ASK 또는 deny로 보냅니다.
- prediction 이후 source가 바뀌면 승인을 무효화합니다.
- sandbox policy가 predicted effect boundary를 실제로 enforce하는지 확인합니다.
- 실행 후 transcript와 file·network·container evidence hash를 append합니다.
- approval fatigue와 repeated identical closure를 측정합니다.
- cache와 failed execution도 effect evidence가 남으면 audit denominator에 포함합니다.
실무 가치 평가
coding agent와 MCP를 운영하는 조직에 직접적인 설계 가치를 제공합니다. 특히 “이 command를 승인했다”는 기록만으로 충분하다고 보는 현재 UI 관행을 깨고, 승인 단위를 workflow closure로 확장해야 한다는 명확한 요구사항을 줍니다.
다만 실제 제품화에는 effect granularity, unknown handling, registry freshness, approval fatigue가 남습니다. parser 기반 disclosure와 runtime capability enforcement를 함께 배치해야 합니다.
결론
approval laundering은 거짓 invocation이 아니라 불완전한 authority representation 문제입니다. entry point가 정확히 기록돼도 transitive workflow가 더 넓은 effect를 실행하면 사용자의 승인과 실제 권한 사용 사이에 구조적 간극이 생깁니다.
해결 방향은 approval 전에 source-backed effect prediction과 provenance를 invocation에 bind하고, 실행 후 evidence를 append하며, sandbox로 예측 범위를 강제하는 것입니다. 사후 trace만으로는 사전 승인의 정보 부족을 복구할 수 없습니다.
댓글