
Claude Code가 참조용으로 보여준 파일을 확인 없이 덮어쓰고 삭제했다——덮어쓰기 전 자동 백업하는 후크(Hook)를 직접 테스트해
요약
Claude Code가 참조용 파일을 확인 없이 덮어쓰거나 삭제할 수 있다는 이슈에 대응하여, 파일 수정 전 자동으로 백업을 생성하는 쉘 스크립트 후크(Hook)의 효과를 직접 테스트한 결과입니다.
핵심 포인트
- Claude Code가 파일 경로를 참조로만 인식해도 덮어쓰기를 수행할 위험이 있음
- cc-safe-setup의 file-edit-backup.sh를 통해 사전 백업 가능
- PreToolUse 단계에서 기존 파일을 타임스탬프와 함께 자동 백업
- git 관리 외 파일의 손실을 방지하기 위한 안전망 구축 방법 제시
먼저 미리 말씀드리자면, 저는 비엔지니어이며 이 글도 AI의 도움을 받아 작성하고 있습니다. 따라서 이것은 "Claude Code의 사양은 이렇다"라는 해설이 아니라, "이런 무서운 보고를 보고 궁금해져서, 직접 방지할 수 있는지 테스트해 보았더니 이랬다"라는 단순한 이야기입니다. 다른 사람의 환경에서도 똑같이 나타날지는 솔직히 알 수 없습니다.
"참조용으로 보여주기만 한 파일을 Claude Code가 확인도 없이 자신의 문서로 덮어쓰고 삭제했다"——그러한 보고가 이슈 #78273에 있었습니다. 보고의 요지는 다음과 같습니다 (이 부분은 제가 직접 경험한 것이 아닌 전언이므로 그대로 전달합니다).
- 사용자는 기존 파일의 위치(경로)를 문맥(Context)으로서 보여주었습니다. "여기에 현재 작업물이 있다"라고 보여주었을 뿐, "여기에 써라"라고 말하지 않았습니다.
- Claude는 해당 파일의 앞 5행을 읽고 "내용과 형식이 있다"는 것을 파악한 뒤,
동일한 경로에 자신의 분석 문서를 통째로 써버려 원래 파일을 파괴했습니다. - 사라진 것은 사용자가 직접 작성한 독자적인 수식 표기법이었습니다. 그 파일은 git 관리 하에 있지 않아 복구 경로가 없었습니다. 보고자는 원래 구조가 영구히 손실되었다고 적었습니다.
무서운 점은 이것이 "망가진 특수한 환경의 이야기"가 아니라, 일상적인 일반적인 사용 방식에서도 일어날 수 있는 형태로 보인다는 것입니다. 파일 경로를 "참조용"으로 전달하는 것은 누구나 합니다. 그것이 쓰기 대상으로 해석되면, 확인 한 마디 없이 덮어쓰기가 실행될 수 있습니다. 게다가 Write는 기존 파일이 있더라도 그대로 덮어씁니다. git에 넣어두지 않았다면 되돌릴 수 없습니다.
만약을 위해 보충하자면, 이것은 보고자 한 명이 작성한 이슈이며 제 환경에서 동일한 일을 재현한 것은 아닙니다. 따라서 "반드시 이렇게 된다"라고 말하지는 않습니다. 다만, 일어날 수 있다면 일어나기 전에 안전망을 칠 수 있을지가 궁금했습니다. 그 부분을 직접 테스트해 보았습니다.
무료로 공개되어 있는 안전용 후크 모음(cc-safe-setup·MIT) 중에, 바로 이 유형에 효과가 있을 법한 file-edit-backup.sh가 있었습니다. 메커니즘은 다음과 같습니다.
PreToolUse(툴이 실행되기 직전에 호출됨)에서Edit와Write를 대상으로 합니다.- 쓰기 대상 파일이 이미 존재할 때만, 덮어쓰기 직전에 그 내용을
~/.claude/file-backups/로 타임스탬프와 함께 복사하여 퇴피(Backup)합니다. - 신규 파일(아직 존재하지 않는 파일)에는 아무것도 하지 않습니다. 퇴피된 파일은 7일 후 자동으로 정리됩니다.
이것이 정말 효과가 있는지 제 환경(WSL2·Claude Code 2.1.20)에서 확인해 보았습니다. 일회용 폴더에 보고 내용과 동일한 "직접 만든 수식 노트(git 관리 외)"를 두고 테스트했습니다.
먼저, 후크에 "이 기존 파일에 Write 한다"라는 모의 입력을 전달했습니다.
echo '{"tool_name":"Write","tool_input":{"file_path":"/tmp/canary/research-notation.txt"}}' \
| bash file-edit-backup.sh
그러자 덮어쓰기가 일어나기 전에 원본이 ~/.claude/file-backups/로 퇴피되었습니다. 그 후 실제로 덮어쓰기를 일으켜 원본을 파괴하고, 퇴피된 내용에서 확인해 보니——직접 만든 수식 표기법이 단 한 줄도 빠짐없이 남아 있었습니다. 퇴피된 파일에서 원래 경로로 다시 복사하면 되돌릴 수 있습니다. 적어도 제 환경에서는 그랬습니다.
# 퇴피된 파일에서 복구하기 (퇴피 경로 → 원래 경로로 되돌리기만 하면 됨)
cp ~/.claude/file-backups/<퇴피된_파일명> /tmp/canary/research-notation.txt
효과가 있다고 적었지만, 만능은 아닙니다. 직접 테스트한 범위 내에서 솔직하게 한계를 명시해 둡니다.
- 신규 파일은 퇴피하지 않습니다. 아직 존재하지 않는 경로에 대한
Write는 퇴피 대상이 아닙니다 (애초에 보호해야 할 내용이 없으므로 당연하지만, "Write라면 무엇이든 보호된다"는 뜻은 아닙니다). 제 환경에서도 존재하지 않는 경로를 전달했을 때는 퇴피 파일이 생성되지 않았습니다. - 덮어쓰기 자체를 막지는 않습니다. 이것은 실행을 중단시키는 후크가 아니라, 직전에 사본을 챙겨두는 것뿐인 안전망입니다. 따라서 덮어쓰기는 일어납니다. 사본이 존재한다는 것을 알고 있고, 그것으로부터 되돌릴 수 있다는 것이 가치이지, "사고가 발생하지 않는다"는 뜻이 아닙니다.
- 동일한 디스크로의 퇴피입니다. 디스크 자체가 유실되는 사고에는 효과가 없습니다. 어디까지나 "실수로 인한 덮어쓰기"에 대한 보험입니다.
그래서 가장 확실한 방어책은 역시 git이라고 생각한다. 보고(Reporting) 과정에서의 사고도 파일이 git에 들어있었다면 복구할 수 있었을 가능성이 높다. git에 다 담을 수 없는 임시 파일이나, 작성 중인 노트에 대한 2중 안전망으로서 이 퇴피(Evacuation) 후크(Hook)가 작동하도록, 나는 이 위치 설정으로 사용하기로 했다.
이것 또한 "이렇게 해야 한다"는 이야기가 아니라, 나의 대처법이다.
- 사라지면 곤란한 것은 우선 git에 넣는다 (가장 확실하게 복구할 수 있는 경로).
- git에 다 넣을 수 없는 임시 파일에는
file-edit-backup.sh를 안전망으로 겹쳐 사용한다. - Claude에게 기존 파일의 경로를 보여줄 때는, "이것은 참조용입니다. 쓰기 대상이 아닙"이라고 한마디 덧붙인다. 보고 사고는 경로를 문맥(Context)으로서 보여준 것이 쓰기 대상으로 해석되어 발생했다. 오해의 여지를 미리 없애두는 것이다.
무료 안전용 후크 모음은 cc-safe-setup (MIT)에 정리하여 공개하고 있다. 위의 file-edit-backup.sh도 이 안에 들어있다.
"사라진 것처럼 보이지만 사실 어디에 남아있는지, 어떻게 복구하는지"를 증상별로 차분하게 구분하고 싶은 사람을 위해, 나의 사고와 복구 기록을 한 권으로 묶은 『Claude Code 사고 방지 핸드북』(¥800 · 제3장까지 무료 · 구매 후 추보(Supplement)는 무상 업데이트)도 있다. 어디까지나 내 환경에서 일어난 일과 그때 했던 일의 기록이다. 곤란을 겪고 있는 분들에게 도움이 된다면 기쁘겠다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기