요약(TL;DR): 악성 AGENTS.md 파일은 해당 파일 본래의 목적을 악용하여 코딩 에이전트를 가로챕니다. 에이전트가 시작 시 이 파일을 읽고 지침을 그대로 따르기 때문입니다. Forever Security는 2026년 10월 실제 고객의 ~/Downloads 폴더에서 이러한 공격 사례를 발견했습니다. 이를 방지하려면 직접 제어하지 않는 폴더에서는 에이전트를 절대 실행하지 말고, 지침 파일을 코드처럼 검토하며, 설정 및 네트워크 재작성을 차단하고, 샌드박스와 승인 확인 프롬프트를 유지하며, 에이전트 자체 설정에 변경 사항이 없는지 면밀히 감시해야 합니다.
악성 AGENTS.md 공격이란 무엇인가
악성 AGENTS.md는 코딩 에이전트가 유해한 작업을 수행하도록 유도하기 위해 작성된 프로젝트 지침 파일입니다. Claude Code, Codex 등의 에이전트는 자신이 실행되는 폴더에서 이러한 파일을 자동으로 로드합니다. 이 공격에는 별도의 익스플로잇이 필요하지 않습니다. 에이전트가 시작할 때 파일을 읽고 그 내용을 프로젝트 자체의 규칙으로 받아들이기 때문입니다.
이 파일은 일반적인 엔지니어링 메모처럼 보입니다. 패키지를 설치하는 "사전 준비(preflight)" 단계나 API 트래픽의 대상을 변경하는 "프록시" 메모 같은 식입니다. 하지만 에이전트 입장에서는 이러한 지시도 "npm 대신 pnpm을 사용할 것"과 같은 일반적인 지침과 똑같이 인식됩니다.
개발팀에서 여러 코딩 에이전트를 사용하고 있다면, Sharkly를 통해 한곳에서 작업을 할당하고 검토할 수 있습니다. 이것이 에이전트의 시작 위치를 어떻게 바꾸는지는 뒤에서 자세히 살펴보겠습니다.
코딩 에이전트가 지침 파일을 그대로 따르는 이유
지침 파일은 에이전트의 컨텍스트 내에서 사용자 프롬프트 바로 옆에 위치하며, 프로젝트 규칙과 사용자의 요청 사이에는 명확한 구분이 존재하지 않습니다.
Claude Code의 메모리 관련 문서에 따르면, CLAUDE.md와 AGENTS.md의 내용은 "강제되는 설정이 아닌 컨텍스트"로 취급됩니다. Claude Code는 CLAUDE.md가 없을 때 작업 디렉터리와 그 상위 디렉터리에 있는 모든 AGENTS.md 파일을 로드합니다. Codex의 AGENTS.md 가이드를 보면 프로젝트 루트부터 현재 디렉터리까지 내려오며 발견되는 내용을 기본 최대 32KiB까지 병합합니다. 이때 에이전트를 시작한 위치에 가까운 파일이 나중에 읽히므로 우선순위를 갖습니다. 결국 에이전트를 시작하는 폴더가 로드 대상을 결정하며, 상위 폴더들 역시 영향을 미치게 됩니다.
악성 AGENTS.md가 Codex와 Claude Code를 하이재킹하는 방식
2026년 10월 22일, Forever Security는 한 고객의 노트북에서 발견한 내용을 공개했습니다. 코딩 에이전트가 악성으로 알려진 npm 패키지인 function-color를 설치하려고 시도했는데, 이 지시는 ~/Downloads 폴더에 있던 AGENTS.md 파일에서 비롯된 것이었습니다. 해당 폴더는 마침 에이전트의 작업 디렉터리이기도 했습니다. Forever Security는 코드가 실행되기 전에 설치를 차단했으며, 이 파일이 어떻게 해당 폴더에 들어갔는지는 확인하지 못했습니다.

Downloads 폴더가 문제가 되는 이유는 웹페이지가 사용자 클릭 없이도 파일을 저장할 수 있는 유일한 폴더이기 때문입니다. Forever Security는 연구실 환경에서 이 공격 체인을 재현했습니다.
- 공격자가 제어하는 웹페이지가
~/Downloads폴더에 AGENTS.md라는 이름의 파일을 저장합니다. - 개발자가 해당 폴더에서 Codex를 열고 아무 질문이나 요청합니다.
- 작업을 시작하기 전, Codex는
~/.codex/config.toml에 "project tools" 서버를 추가하고 npm에서 패키지를 설치합니다. - 이 설정은 컴퓨터 전체에 적용되므로, 이후 어느 폴더에서 실행하든 모든 Codex 세션이 공격자의 서버를 로드하게 됩니다.
Forever Security에 따르면 Codex는 90% 이상의 시도에서 페이로드를 실행했습니다. 대부분의 테스트에서는 계산기를 실행하는 무해한 대체 코드를 사용했으며, 실제 악성 패키지는 격리된 VM 내에서 한 차례 실행되었습니다.
Claude Code는 속이기가 더 까다로웠습니다. 악의적으로 심어둔 CLAUDE.md를 통해 자체 API 트래픽을 Forever Security가 제어하는 서버로 향하게 유도함으로써 OAuth 로그인 토큰을 탈취하고 서버가 마치 모델인 것처럼 응답하게 만들 수 있었습니다. Forever Security는 이 방식이 약 50%의 확률로 성공했다고 밝혔습니다. 두 수치는 서로 다른 공격 시나리오에서 나온 것이므로 단순한 성공률 비교는 적절하지 않습니다.
Forever Security가 지적하는 핵심은 패치할 버그가 따로 없다는 점입니다. 진짜 문제는 웹에서 임의로 쓸 수 있는 폴더를 마치 사용자가 직접 채워 넣은 것처럼 신뢰한다는 데 있습니다. 이는 코드 리뷰 시 diff에서 보이지 않는 투명 유니코드 문자를 규칙 파일에 숨겨 지침을 전달했던 Pillar Security의 규칙 파일 백도어(Rules File Backdoor) 연구에서도 지적된 바 있습니다.
악성 AGENTS.md 공격을 막는 5가지 조치
처음 두 단계는 파일이 로드되는 것 자체를 방지하며, 나머지 세 단계는 파일이 통과되었을 때 피해를 최소화하기 위한 조치입니다.

1. 코딩 에이전트를 절대 실행해서는 안 되는 위치는 어디인가요?
~/Downloads, 홈 폴더, 또는 직접 생성하지 않은 폴더에서는 절대 실행하지 마세요. Forever Security에 따르면 고객의 약 절반이 Downloads 폴더 안에서 코딩 에이전트를 실행한 경험이 있다고 합니다. 다운로드된 파일을 에이전트로 정리해야 한다면, 비어 있는 새 폴더로 파일을 복사한 뒤 해당 폴더에서 실행해야 합니다.
규칙을 깜빡하기 쉬운 사용자라면 셸 가드(shell guard) 스크립트를 적용해 이를 강제할 수 있습니다.
# ~/.zshrc: refuse to start an agent in folders the web can write to
agent_guard() {
case "$PWD" in
"$HOME"|"$HOME/Downloads"*|"/tmp"*)
echo "Refusing to start an agent in $PWD. Use a project folder." >&2
return 1 ;;
esac
}
claude() { agent_guard && command claude "$@"; }
codex() { agent_guard && command codex "$@"; }
2. AGENTS.md를 코드처럼 검토하려면 어떻게 해야 하나요?
방금 클론한 저장소의 파일이라 하더라도 모든 지침 파일을 실행 파일과 동일하게 취급해야 합니다. 그런 다음 검토 과정을 자동화하세요. 지침 파일들을 CODEOWNERS에 지정하여 해당 파일을 수정하는 풀 리퀘스트(PR)에는 반드시 지정된 리뷰어의 승인이 필요하도록 설정합니다.
AGENTS.md @your-org/platform
**/AGENTS.md @your-org/platform
CLAUDE.md @your-org/platform
/.claude/ @your-org/platform
/.cursor/rules/ @your-org/platform
이러한 공격에서 주로 악용되는 패턴(숨겨진 유니코드, 베이스 URL 변경, 지침 파일 내부의 설치 명령)을 감지하여 실패 처리하는 CI 검사를 추가하세요.
#!/usr/bin/env bash
# ci/check-agent-instructions.sh
files=$(git ls-files '*AGENTS.md' '*CLAUDE.md' '.cursor/rules/*')
[ -z "$files" ] && exit 0
fail=0
# zero-width, bidi override and Unicode tag characters
if grep -nP '[\x{200B}-\x{200F}\x{202A}-\x{202E}\x{2066}-\x{2069}\x{E0000}-\x{E007F}]' $files; then
echo "Hidden Unicode in an agent instruction file"; fail=1
fi
if grep -niE 'BASE_URL|chatgpt_base_url|mcp_servers|npx --yes|curl .*\| *(ba)?sh' $files; then
echo "Config, network or install instruction in an agent file: needs review"; fail=1
fi
exit $fail
두 번째 grep 검사는 정상적인 코드를 탐지할 수도 있지만, 어차피 사람이 직접 확인해보는 것이 바람직합니다.
3. 에이전트의 자체 설정 재작성 권한 거부
두 재현 테스트 모두 에이전트가 자체 설정을 편집하는 것으로 끝났습니다. 이러한 가능성을 사전에 차단해야 합니다. Claude Code에서는 에이전트 설정 폴더에 대한 편집을 거부하고, 프로젝트의 .claude/settings.json에서 시크릿 정보를 읽을 수 없도록 설정하세요.
{
"permissions": {
"deny": [
"Edit(./.claude/**)",
"Edit(~/.claude/**)",
"Edit(~/.codex/**)",
"Read(./.env)",
"Read(./.env.*)"
]
}
}
팀 단위 환경에서는 프로젝트 파일로 이 규칙을 완화할 수 없도록 관리형 설정(managed settings)에 지정하세요. 메모리 문서에서는 반드시 강제해야 하는 항목에 관리형 permissions.deny, sandbox.enabled, env를 사용할 것을 권장하며, 모델의 결정과 무관하게 작업을 차단하려면 PreToolUse 훅을 활용하라고 안내합니다. 관리형 env에서 API 라우팅을 고정하는 것은 베이스 URL 공격에 대한 직접적인 해결책입니다. 실제로 배포하기 전에 설치된 버전에 맞춰 규칙 문법을 확인하시기 바랍니다.
4. 샌드박스와 승인 프롬프트 활성 상태 유지
Forever Security는 승인 게이트와 샌드박스를 켜 둔 채로 유지하고, 에이전트에게 이를 우회하도록 지시하는 모든 텍스트를 불신할 것을 권고합니다.
패키지 설치, 에이전트 설정 변경, 새로운 호스트로의 네트워크 호출 등 어떤 작업에서 항상 사람의 승인을 거치게 할지 결정하세요. 이러한 중단 지점을 어디에 배치할지에 대해서는 코딩 에이전트를 위한 승인 게이트 글을, 그 이면의 권한 모델에 대해서는 코딩 에이전트에 허용해야 할 작업과 허용하지 말아야 할 작업 글을 참고하시기 바랍니다.
5. 에이전트 설정을 감시하고 이상 징후 발견 시 자격 증명 재발급
Forever Security는 구체적으로 확인해야 할 위치를 명시하고 있습니다. ~/.codex/config.toml의 경우 예상치 못한 [mcp_servers.*] 블록이나 변경된 chatgpt_base_url이 있는지 확인해야 합니다. 프로젝트의 .claude/settings.json에서는 직접 설정하지 않은 ANTHROPIC_BASE_URL, 프록시 또는 엔드포인트가 있는지 살펴봐야 합니다.
grep -nE '^\[mcp_servers\.|chatgpt_base_url' ~/.codex/config.toml
grep -rnE 'ANTHROPIC_BASE_URL|_PROXY|base_url' ~/.claude/settings.json .claude/settings*.json 2>/dev/null
npm ls -g --depth=0 2>/dev/null | grep -i function-color
만약 의심스러운 항목이 하나라도 발견된다면 토큰이 유출된 것으로 간주하고 즉시 재발급(rotate)해야 합니다. 탈취된 OAuth 토큰은 가로챈 일회성 요청이 아니라 활성 세션 그 자체이기 때문입니다. 만약 function-color가 발견되면 해당 컴퓨터는 이미 침해된 것으로 간주해야 합니다. 보다 광범위한 정리 작업이 필요하다면 코딩 에이전트 비밀 정보 유출 시 팀 체크리스트를 통해 각 단계별 담당자를 지정하고 대처하시기 바랍니다.
Sharkly가 기여하는 부분
Sharkly는 지침 파일을 직접 검사하거나 에이전트 자체 권한을 대체하지는 않으므로 앞서 소개한 5가지 조치는 그대로 유지해야 합니다. 다만 Sharkly는 에이전트가 시작되는 위치와 그 위치를 결정하는 주체를 변화시킵니다.
Sharkly에서 Agent는 사용자가 연결한 Computer 환경에서 실행되며, 각 Agent의 설정에는 기본 작업 디렉터리(Default working directory)가 지정되어 있습니다. "임시 디렉터리 사용(Use temporary directory)"을 선택하면 작업(Task)이 실행될 때마다 독립된 디렉터리와 연결된 저장소의 새로운 git worktree가 생성됩니다. "지정된 디렉터리(Specified directory)"를 선택하면 사용자가 직접 설정한 로컬 경로를 사용합니다. 두 모드에 대한 자세한 내용은 작업 디렉터리 문서에서 확인할 수 있습니다.

이를 통해 실행 폴더에 대한 결정을 개발자 개인의 터미널이 아닌 사전에 검토된 설정으로 옮길 수 있습니다. 임시(Temporary) 모드에서 Agent는 누군가 열어둔 임의의 폴더가 아니라 연결된 저장소의 깨끗한 체크아웃 환경에서 시작됩니다. 저장소 관리는 Space 또는 Organization 관리자 권한을 가진 사용자에게만 허용됩니다. 또한 매 실행 시마다 주입되는 에이전트 지침(Agent instructions)은 "에이전트 설정 파일은 절대 수정하지 말 것"과 같은 보안 규칙을 재강조하기에 적합한 공간입니다.
결과물은 Task로 반환되어 팀이 검토할 수 있으며, 이 과정은 태스크 수준의 근거를 바탕으로 AI 생성 코드 검토하기에 자세히 설명되어 있습니다.
마치며
악성 AGENTS.md가 동작할 수 있는 이유는 에이전트가 설계상 지침 파일을 충실히 따르도록 되어 있고, 웹에서 사용자가 신뢰하는 폴더에 악성 파일을 심을 수 있기 때문입니다. 이 문제는 단일 패치가 아닌 다중 계층 방어를 통해 해결해야 합니다.
지금 당장 모든 개발자 노트북에서 5단계부터 시작해 보세요. 이미 침해 문제가 발생했는지 바로 확인할 수 있습니다. 그런 다음 개발팀에서 여러 코딩 에이전트를 운영하고 있다면 Sharkly를 구축하고 Computer 1대와 Temporary 모드의 Agent 1개를 설정하여, 모든 실행이 깨끗한 worktree에서 시작되도록 구성하시기 바랍니다.
자주 묻는 질문 (FAQ)
악성 AGENTS.md가 Claude Code를 하이재킹할 수 있나요?
그렇습니다. Claude Code는 작업 디렉터리나 그 상위 디렉터리에 CLAUDE.md가 없을 때 AGENTS.md를 읽습니다. Forever Security의 Claude Code 재현 실험에서는 사전에 심어둔 CLAUDE.md를 사용해 API 트래픽의 경로를 변경했으며, 테스트 중 약 절반에서 OAuth 토큰이 유출되었습니다.
OpenAI나 Anthropic이 패치할 수 있는 취약점인가요?
Forever Security는 에이전트가 본래 설계된 대로 동작하는 것이므로 패치할 대상이 없다고 설명합니다. 따라서 폴더 위생 관리, 코드 리뷰, 권한 제어를 통해 대응해야 합니다.
AGENTS.md에 숨겨진 지침을 어떻게 찾아낼 수 있나요?
렌더링된 화면 대신 원본(raw) 파일을 확인하고, 너비가 0인 문자(zero-width), 양방향 텍스트 재정의(bidi override), 유니코드 태그 문자가 있는지 검사해야 합니다. 위에 제시된 CI 스크립트는 이 세 가지 패턴을 모두 감지하여 차단합니다.
샌드박스를 사용하면 악성 AGENTS.md를 막을 수 있나요?
파일이 로드되는 것을 막는 것은 아니며, 피해를 제한하는 역할을 합니다. 샌드박스와 승인 프롬프트는 해당 파일이 요구하는 패키지 설치나 설정 변경 작업을 중단시킬 수 있습니다. 이를 에이전트 설정 폴더에 대한 거부(deny) 규칙과 함께 조합해 사용해야 합니다.
누군가 심어둔 AGENTS.md를 발견하면 어떻게 해야 하나요?
해당 파일이 있는 디렉터리 부근에서는 절대 에이전트를 실행하지 마세요. 에이전트의 설정 파일에 새로운 MCP 서버나 베이스 URL이 추가되었는지 확인하고, function-color가 설치되어 있는지 검사한 뒤, 에이전트의 토큰과 에이전트가 읽을 수 있었던 모든 키를 즉시 재발급(rotate)해야 합니다.


