코딩 에이전트가 다운로드 파일을 신뢰하지 않도록 막기: 워크스페이스 사전 검사 구축
요약
AI 코딩 에이전트가 신뢰할 수 없는 다운로드 폴더의 텍스트 파일을 지침으로 오인하여 악용될 보안 취약점이 보고되었습니다. 이 문제는 에이전트가 작업 디렉터리의 모든 텍스트를 무분별하게 신뢰하는 데서 기인합니다. 이에 대한 방어책으로, 실행 전 지정된 로컬 허용 목록(allowlist)과 일치하는지 검사하는 사전 검사 스크립트 구축이 제안됩니다.
핵심 포인트
- 에이전트는 다운로드 폴더 등 신뢰 경계 외부의 텍스트를 지침으로 오인할 수 있습니다.
- 악성 파일(예: AGENTS.md)은 에이전트를 속여 설정을 변경하거나 패키지를 설치하도록 유도합니다.
- 방어책은 사전 검사 스크립트 구축이며, 실행 전 작업 디렉터리를 명시적으로 확인해야 합니다.
- 이는 범용적인 보안 솔루션이 아니며, 팀 정책에 맞는 로컬 허용 목록 설정이 필수입니다.
다운로드된 텍스트 파일은 일반적으로 스스로 실행될 수 없습니다. 하지만 AI 코딩 에이전트는 이를 읽고, 지침으로 해석하며, 설명된 명령을 실행할 수 있습니다.
이는 Forever Security의 최근 보고서에서 발견된 불편한 취약점입니다. 연구원들은 고객의 Downloads 폴더에서 악성 AGENTS.md 파일을 발견했습니다. 코딩 에이전트가 해당 디렉터리에서 시작했을 때, 이 파일은 에이전트에게 설정을 변경하고 악성 npm 패키지를 설치하도록 설득하려고 시도했습니다. 문제는 마크다운(Markdown) 형식이 운영 체제에서 실행 가능하게 되었다는 것이 아니었습니다. 문제가 된 것은 행동할 권한을 가진 에이전트가 작업 디렉터리에 있는 텍스트를 신뢰하는 지침으로 취급했다는 점입니다. Forever Security의 기술 보고서는 해당 사건과 재현 방법을 설명하며, BleepingComputer의 보도 또한 이 연구와 그 실제적인 함의를 요약합니다.
이 글은 해당 사건을 작고 구축 가능한 방어책, 즉 광범위하거나 신뢰할 수 없는 디렉터리에서 에이전트가 실행되는 것을 거부하고 지침 파일이 명시적인 로컬 허용 목록(allowlist)과 일치하는지 요구하는 사전 검사 스크립트(preflight script)로 만듭니다. 이것은 악성코드 탐지기는 아니며, 그 자체만으로는 에이전트를 안전하게 만들 수 없습니다. 이는 에이전트가 초기 컨텍스트를 읽기 전에 의도적인 체크포인트를 추가합니다.
공개 고지: 본 내용은 실제 사고 보고서나 Codex 또는 Claude Code의 실습 테스트 기반 튜토리얼입니다. 아래 Python 사전 검사 스크립트는 로컬 예시입니다. 이를 에이전트의 문서화된 실행 동작과 팀 정책에 맞게 조정하십시오.
작업 디렉터리가 신뢰 경계(trust boundary)인 이유
지침 파일(instruction file)은 에이전트가 이를 읽고 따르기 때문에 유용합니다. AGENTS.md, CLAUDE.md 및 유사한 파일들은 빌드 명령어, 코딩 컨벤션 또는 프로젝트별 제약 조건을 설명할 수 있습니다. 이러한 파일의 존재 자체가 본질적으로 의심스러운 것은 아닙니다. 중요한 질문은 해당 파일이 예상되었는지, 검토되었는지, 그리고 이 작업 범위 내에 있는가입니다.
보고된 사건에서 에이전트는 ~/Downloads 폴더에서 실행되었습니다. Forever Security는 웹페이지가 여기에 파일을 배치할 수 있으며, 그 후 에이전트가 이를 로컬 지침으로 처리했다고 밝혔습니다. 해당 기관의 테스트 결과에 따르면 재구성된 Codex 공격은 시도 중 90% 이상 성공하는 것으로 보고되었습니다. Claude Code의 경우, 연구원들은 다른 구성 리디렉션 경로를 테스트했으며 약 절반의 시도에서 성공을 보고했습니다. 이는 모든 기기, 프롬프트, 버전 또는 구성을 위한 보편적인 성공률이 아니라 공급업체-연구원 간의 테스트 결과입니다. 원본 보고서에서는 테스트 설정과 한계에 대해 설명합니다.
BleepingComputer는 해당 공격이 에이전트가 악성 파일과 같은 디렉토리에서 시작되도록 요구했다고 보도했습니다(https://www.bleepingcomputer.com/news/security/ai-coding-agents-hijacked-using-agentsmd-file-in-downloads-folder/). 이들이 제시한 권장 사항에는 에이전트를 의도된 프로젝트의 루트에서 시작하는 것, 생소한 지침 파일을 검토하는 것, 그리고 승인 및 샌드박스 제어(sandbox controls)를 활성화 상태로 유지하는 것이 포함되었습니다.
이는 유용한 심층 방어(defense-in-depth) 규칙을 시사합니다. 즉, 에이전트가 시작되는 디렉토리는 의도적으로 선택되어야 하며, 그 지침 파일들은 눈에 보이지 않는 설정(configuration)으로 취급되기보다는 검토해야 할 입력값(inputs)으로 다루어져야 합니다. 사전 점검 게이트(preflight gate)는 이 규칙의 일부를 일관되게 강제할 수 있습니다.
우리가 구축하는 방어책
이 스크립트는 에이전트를 시작하기 전에 네 가지 작업을 수행합니다:
- 현재 작업 디렉터리를 확인하고 Git 저장소의 루트를 찾습니다.
- 다운로드 폴더나 홈 디렉터리 자체와 같이 위험도가 높은 일반적인 위치에서는 실행을 거부합니다.
- 저장소에서 에이전트 지침 파일들을 찾아, 각 파일은 예상되는 SHA-256 해시와 함께 검토된 매니페스트에 나열되어야 합니다.
- 지침 파일이 매니페스트에 누락되었거나, 검토 이후 변경되었거나, 저장소 외부에 위치할 경우 중지합니다.
이 설계는 의도적으로 'fail-closed' 방식을 채택합니다. 지침 파일을 추가하거나 편집하는 것은 스크립트가 조용히 수락하는 것이 아니라, 명시적인 검토 단계를 거쳐야 합니다. 이 시스템은 "나쁜" 구문을 파싱하지 않습니다. 이는 취약한 필터 역할을 할 수 있습니다. 공격자는 요청을 여러 방식으로 표현할 수 있으며, 무해한 프로젝트라 하더라도 경고나 예제에서 위험한 명령어를 합법적으로 언급할 수 있기 때문입니다.
해시 허용 목록(hash allowlist)은 해당 파일이 누군가 승인했던 버전과 일치한다는 것만을 증명합니다. 이는 승인된 내용 자체가 안전하다는 것을 증명하지 못하며, 심지어 검토를 거쳐 실수로 승인된 악의적인 변경에 대해서도 보호해주지 못합니다. 따라서 인간의 검토와 최소 권한 원칙(least privilege)을 결합해야 합니다.
1단계: 작은 매니페스트 추가하기
저장소 루트에 .agent-instructions.sha256 파일을 생성합니다. 유지 관리자가 검토한 지침 파일만 한 줄에 하나씩 다음 형식으로 나열합니다:
<sha256> AGENTS.md
<sha256> packages/api/AGENTS.md
macOS 또는 Linux에서 검토된 파일의 해시를 생성하려면 다음 명령을 실행합니다:
shasum -a 256 AGENTS.md
sha256sum이 있는 시스템에서는 이 방법도 작동합니다:
sha256sum AGENTS.md
생성된 다이제스트(digest)와 상대 경로를 매니페스트에 복사합니다. 기록하기 전에 나열된 모든 지침 파일을 텍스트로 검토해야 합니다. 매니페스트와 지침 파일은 함께 커밋하여 코드 리뷰에서 정확히 무엇이 변경되었는지 보여줄 수 있도록 해야 합니다. 지침 파일이나 매니페스트에는 비밀 정보(secrets)를 넣지 마십시오.
만약 팀에 아직 지침 파일이 없다면, 매니페스트는 처음에 주석만 포함할 수 있습니다. 이 경우, 첫 번째 새로운 AGENTS.md 파일은 검토와 승인된 다이제스트를 받을 때까지 차단됩니다.
2단계: 사전 검사 스크립트 생성
이 파일을 scripts/agent_preflight.py로 저장합니다:
#!/usr/bin/env python3
"""코딩 에이전트를 실행하기 전 실패 시 종료(Fail-closed) 체크를 수행합니다."""
...
이 스크립트는 Python의 표준 라이브러리만을 사용합니다. 저장소 루트 디렉터리가 의도된 범위를 나타내기 때문에 Git이 필요합니다. 이 스크립트는 .git과 node_modules를 제외하면서 재귀적으로 검색하며, 프로젝트 레이아웃에 맞게 제외 항목을 조정해야 합니다. 신뢰할 수 있는 지침으로 따라가기보다는, 루트 외부로 해결되는 심볼릭 링크(Symlinks)는 차단합니다.
3단계: 에이전트 실행 전 테스트
저장소 루트에서 다음 명령어를 실행합니다:
python3 scripts/agent_preflight.py
PASS가 출력된 후에만 해당 디렉터리에서 코딩 에이전트를 실행해야 합니다. 래퍼(wrapper)를 사용하여 이 검사를 잊지 않도록 만들 수 있습니다:
#!/usr/bin/env bash
set -euo pipefail
python3 scripts/agent_preflight.py
...
이 래퍼를 scripts/codex-safe로 저장하고, chmod +x scripts/codex-safe 명령어로 실행 권한을 부여한 다음, 저장소 루트에서 호출합니다. 여기서 codex는 사용자의 에이전트가 문서화된 명령어(command)로 대체해야 합니다. 이 래퍼는 프로세스를 시작하기 전에 검사하는 것이며, 해당 에이전트 자체의 샌드박스(sandbox), 권한 모델(permission model) 또는 구성 제어(configuration controls)를 대체할 수 없습니다.
래퍼를 채택하기 전에, 사용자의 에이전트가 지침 파일(instruction files)을 예상하는 방식으로 읽는지 확인해야 합니다. 제품마다 다르며 동작 방식이 변경될 수 있습니다. Codex의 AGENTS.md 가이드는 지침 파일의 동작 방식과 우선순위(precedence)를 문서화하고 있습니다. 관리되는 격리 패턴(managed isolation pattern)의 경우, Cloudflare의 코딩 에이전트 샌드박스 가이드는 작업별 Linux 컨테이너에서 에이전트를 실행하고 접근할 수 있는 호스트 이름(hostnames)을 제어하는 방법을 설명합니다. 컨테이너는 피해 반경(blast radius)을 줄일 수 있지만, 여기에 마운트된 비밀 정보(secrets)와 허용된 네트워크 경로는 여전히 중요합니다.
4단계: 실패 경로 테스트
정상 에이전트 명령어에 연결하기 전에, 무해한 임시 Git 저장소로 게이트를 테스트하십시오:
- 지침 파일이 없는 깨끗한 저장소: 주석만 포함하는 매니페스트를 생성합니다. 스크립트는 승인된 파일이 0개임을 표시하며
PASS를 출력해야 합니다. - 예상치 못한 파일: 매니페스트를 변경하지 않고
AGENTS.md파일을 추가합니다. 스크립트는 0이 아닌 상태 코드를 반환하고 이를 승인되지 않은 것으로 식별해야 합니다. - 수정된 승인 파일: 해시(hash) 값을 기록한 다음, 한 문자를 변경합니다. 스크립트는 검토된 파일이 변경되었다고 보고해야 합니다.
- 잘못된 디렉토리: 저장소의 하위 디렉토리에서 스크립트를 실행합니다. 루트(root)에서 시작하도록 요청해야 합니다.
- 다운로드 폴더:
Downloads아래에 무해한 테스트 저장소를 배치하고 그곳에서 스크립트를 실행합니다. 에이전트가 호출되기 전에 차단해야 합니다.
사고로 발생한 악성 파일을 복사하거나 실행하여 테스트하지 마십시오. 무해한 테스트 파일만으로 사전 검사 로직을 확인하기에 충분합니다.
성공적인 사전 검사는 현재 디렉토리와 지침 파일 인벤토리가 로컬 기대치와 일치한다는 것만을 의미합니다. 에이전트가 읽을 수 있는 모든 파일을 검사하거나, 검토된 지침이 무해하다는 것을 증명하거나, 이슈 텍스트 또는 웹 페이지에서 프롬프트 주입(prompt injection)을 차단하거나, 승인된 지침이 위험한 작업을 요청하는 것을 막지는 못합니다. 이를 더 큰 워크플로우의 하나의 게이트로 취급하십시오.
사전 검사가 대체할 수 없는 것들
승인 기능을 유지하십시오. 파일은 에이전트에게 승인을 우회하거나 샌드박스(sandbox)를 비활성화하도록 요청할 수 있습니다. 그러한 요청 자체가 중단하고 검사해야 할 이유이며, 더 많은 접근 권한을 부여할 이유는 아닙니다. 지침 파일에서 필요하다고 명시한다고 해서 "위험하게 우회(dangerously bypass)" 옵션이 있는 명령어를 절대 실행하지 마십시오.
파일 시스템 액세스 범위 제한. 저장소 루트에서 시작하는 것은 컨텍스트를 좁게 유지하는 데 도움이 되지만, 작업 디렉토리가 자동으로 완전한 보안 샌드박스를 의미하지는 않습니다. 에이전트가 지원하는 제약 조건을 사용하여 관련 없는 홈 디렉토리 파일, 자격 증명(credentials), 시스템 구성을 거부하십시오.
네트워크 및 비밀 정보 제어. 에이전트가 네트워크에 접근하거나 토큰을 읽을 수 있는 경우, 악성 지침은 이러한 기능을 목표로 할 수 있습니다. 에이전트에게 작업에 필요한 자격 증명만 제공하고, 생소한 저장소나 의존성을 위해서는 격리된 환경을 사용하십시오.
구성 변경 사항 검사. 보고된 공격은 프로젝트 파일뿐만 아니라 에이전트 수준의 설정을 수정하려고 시도했습니다. 전역 구성, MCP 서버, API 기본 URL, 셸 시작 파일 및 자격 증명 저장소에 대한 변경 사항을 검토하십시오. 예상치 못한 변경 사항은 잠재적인 손상으로 간주하고 제공업체의 계정 보안 지침을 따르십시오.
의심되는 노출은 사고로 처리. 알 수 없는 지침 파일이 소비된 경우, 해당 세션 사용을 중단하십시오. 관련 로그와 구성 변경 사항을 보존하고, 증거 기록 후 파일만 제거하며, 에이전트가 접근할 수 있었던 자격 증명을 로테이션(rotate)하십시오. 의심스러운 패키지가 실행되었다면, 환경을 격리하고 보안 팀과 협력하십시오. Forever Security는 노출된 토큰을 손상된 것으로 간주할 것을 특히 권장합니다. 올바른 대응은 에이전트가 접근할 수 있었던 자격 증명 및 시스템에 따라 달라집니다.
에이전트 지침 파일 검토 체크리스트
지침 파일을 승인하거나 해시를 업데이트하기 전에 다음 사항을 확인하십시오:
- 저장소 외부 또는 전역 구성에서 파일을 편집하도록 요청하는가?
- 패키지를 설치하거나, 원격 스크립트를 실행하거나, 새로운 MCP/도구 서버를 등록하는가?
- API 기본 URL, 프록시, 자격 증명 또는 인증 설정을 변경하는가?
- 승인(approvals), 샌드박싱(sandboxing) 또는 보안 검사를 비활성화하도록 요청하는가?
- 해당 명령이 프로젝트에 필요한지, 고정되어 있거나 달리 검증 가능하며 설명 가능한지?
- 파일의 출처와 작성자가 저장소가 예상하는 것과 일치하는가?
그런 다음 지침과 매니페스트(manifest) 모두에 대해 Git diff를 검토하십시오. 의미 있는 코드 검토 없이 해시만 업데이트하는 것은 알려지지 않은 지침을 승인된 알려지지 않은 지침으로 바꿀 뿐입니다.
실질적인 규칙
이 사건이 모든 AGENTS.md 파일이 악의적이라는 것을 의미하거나 에이전트가 프로젝트 지침을 무시해야 한다는 것을 의미하지는 않습니다. 이는 에이전트의 시작 디렉터리가 보안 결정임을 보여줍니다. 전용 프로젝트 워크스페이스(project workspace)를 사용하고, 지침 파일을 코드와 인접한 설정(code-adjacent configuration)으로 검토하며, 에이전트가 이를 읽기 전에 명시적인 사전 점검(preflight)을 요구해야 합니다.
작은 스크립트만으로는 신뢰 문제를 해결할 수 없습니다. 하지만 한 가지 중요한 신뢰 결정을 가시적이고 반복 가능하게 만들 수는 있습니다. 즉, “내가 열고자 했던 프로젝트가 맞는지, 그리고 내가 검토했던 지침이 정확한지?”입니다. 자격 증명(credentials), 코드, 터미널에 접근하는 에이전트 워크플로우의 경우, 이는 첫 번째 프롬프트 전에 물어보기 좋은 질문입니다.
코딩 에이전트에 대한 시작점 확인 절차를 추가했습니까, 아니면 수동 검토에 의존하고 있습니까? 어떤 것을 차단하기를 원합니까?
출처 (Sources)
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기