Claude Code 소스코드, NPM 레지스트리의 Source Map 파일을 통해 유출
Claude Code's source code has been leaked via a map file in their NPM registry
TL;DR Highlight
Anthropic의 AI 코딩 도구 Claude Code의 소스코드가 NPM 패키지에 포함된 source map 파일을 통해 외부에 노출됐으며, 미공개 기능 로드맵과 내부 보안 메커니즘까지 함께 드러났다.
Who Should Read
NPM 패키지를 배포하거나 유지보수하는 개발자, 그리고 AI 코딩 에이전트의 내부 아키텍처나 Anthropic의 제품 전략에 관심 있는 개발자.
Core Mechanics
- Claude Code의 NPM 패키지(@anthropic-ai/claude-code)에 번들된 JavaScript 파일과 함께 source map(.map) 파일이 같이 배포되면서 원본 TypeScript 소스코드가 그대로 노출됐다. Source map은 원래 디버깅용으로 압축된 JS 코드를 원본 코드로 역추적할 수 있게 해주는 파일인데, 이걸 프로덕션 패키지에 포함시킨 게 문제였다.
- Anthropic은 뒤늦게 해당 버전(v2.x)을 조치했는데, npm unpublish(실제로 버전 삭제)가 아닌 npm deprecate(삭제 없이 '폐기됨' 표시만)를 써서 패키지가 여전히 다운로드 가능한 상태로 남았다. 댓글에서는 이걸 두고 'Claude한테 unpublish 해달라고 했더니 deprecate를 해온 것 같은 느낌'이라며 풍자했다.
- 소스코드에서 미공개 기능들의 feature flag가 다수 발견됐다. 가장 주목받은 건 'kairos'라는 코드명의 'assistant mode', 타마고치 스타일의 ASCII 아트 가상 펫 시스템인 'Buddy System(/buddy)', 그리고 Anthropic 직원이 오픈소스 기여 시 내부 정보를 커밋/PR에서 제거하는 'Undercover mode'다.
- ANTI_DISTILLATION_CC라는 내부 플래그도 드러났다. 이 기능이 활성화되면 모든 API 요청에 anti_distillation: ['fake_tools']를 주입해서, 서버 측에서 가짜 tool 정의를 시스템 프롬프트에 몰래 삽입한다. 경쟁사가 Claude Code의 API 트래픽을 스크래핑해서 모델을 학습시키려는 시도(distillation)를 방해하기 위한 일종의 데이터 독살(data poisoning) 방어책이다.
- 사용자 프롬프트에서 부정적 감정이나 특정 키워드를 감지하는 정규식(regex)도 발견됐으며, 해당 내용은 로깅된다고 코드에 명시돼 있다. 이는 어떤 표현이 시스템에서 모니터링되는지를 외부에 노출시킨 셈이다.
- 소스코드 품질 면에서도 눈에 띄는 부분이 있었다. src/cli/print.ts 파일 내 특정 함수 하나가 3,167줄, 최대 12단계 중첩, cyclomatic complexity(코드 복잡도 지표) 약 486, 파라미터 12개+옵션 객체 16개 속성, 내부 함수 21개를 가지고 있으며, agent 루프·SIGINT 처리·AWS 인증·MCP 생명주기 등을 한 함수에서 모두 담당한다. 댓글에서는 '최소 8~10개 모듈로 분리해야 한다'고 지적했다.
- 이번이 처음이 아니라는 점도 지적됐다. 2025년 2월에도 비슷한 방식으로 Claude Code 소스가 노출된 적이 있으며, 당시에도 HN에서 화제가 됐다.
- Claude Code 내부에서 HTTP 요청에 Axios를 사용한다는 사실도 확인됐다. 공교롭게도 같은 날 HN에 Axios 관련 다른 글이 올라와 있어서, 두 소식이 함께 언급되며 화제가 됐다.
Evidence
- npm deprecate vs unpublish 실수에 대해, 한 댓글러는 'npm deprecate는 패키지를 레지스트리에서 제거하지 않고 폐기 표시만 남겨서 여전히 다운로드 가능하다. 실제로 지우려면 npm unpublish를 썼어야 했다'고 정확한 차이를 설명하며, Anthropic이 잘못된 명령어를 사용한 것이 오히려 Claude가 작업을 잘못 이해하고 처리한 것 같은 뉘앙스를 준다고 풍자했다.
- 유출의 심각성을 둘러싼 논쟁이 있었다. 일부는 'TypeScript/JS는 기계어도 아니고 원래 obfuscated 코드는 어느 정도 역추적 가능하니 CLI 도구 코드 유출이 뭐가 대단하냐, 차라리 오픈소스로 풀면 된다'는 입장이었다. 반면 다른 쪽에서는 'Google이나 OpenAI가 공개한 것은 Agent SDK라는 툴킷이지, 자사 플래그십 에이전트가 내부적으로 어떻게 동작하는지 보여주는 코드가 아니다. 로드맵과 내부 아키텍처까지 드러난 이번 유출은 차원이 다르다'고 반박했다.
- 미공개 /buddy 기능에 대해서는 꽤 상세한 분석이 공유됐다. 한 댓글러가 코드를 분석해 이 기능이 4월 1일 만우절 이스터에그로 출시 예정이었으며, 18가지 종, 희귀도, 능력치, 모자, 눈 모양 등이 사용자 계정의 UUID를 seed로 한 결정적(deterministic) 알고리즘으로 생성된다는 걸 알아내고, 미리 자신의 버디를 확인할 수 있는 웹사이트(claudebuddychecker.netlify.app)까지 만들어 공유했다.
- ANTI_DISTILLATION 기능 발견에 대해서는 여러 명이 주목했다. 가짜 tool 정의를 API 응답에 몰래 끼워넣어 경쟁사의 학습 데이터를 오염시키는 방어책이라는 점에서, 'AI 회사들이 이미 이런 종류의 방어 메커니즘을 상용 제품에 구현하고 있다'는 사실 자체가 흥미롭다는 반응이 많았다.
- 법적 문제에 대한 우려도 제기됐다. 유출된 코드를 AI로 분석해서 유사한 시스템을 재구현하는 게 법적으로 괜찮은지 묻는 댓글이 있었고, '오염된 물건(tainted goods)처럼 접근하지 않는 게 나을 수 있다'는 조심스러운 의견도 나왔다. 한편으로는 'AI 모델들이 이미 수십억 개의 오픈소스 코드로 학습됐는데 도덕적 문제가 있냐'며 가볍게 보는 시각도 있었다.
How to Apply
- NPM 패키지를 배포하는 경우, 빌드 설정에서 source map 파일이 배포 번들에 포함되지 않도록 반드시 확인해야 한다. Webpack이라면 devtool 옵션을 'hidden-source-map'으로 설정하거나 .npmignore에 *.map을 추가해 내부 로직이 역추적되는 것을 막을 수 있다.
- 패키지 버전을 긴급하게 내려야 할 때, npm deprecate가 아닌 npm unpublish [패키지명]@[버전]을 사용해야 레지스트리에서 실제로 삭제된다. npm deprecate는 표시만 남기고 파일은 그대로 남아 다운로드 가능하므로, 보안 이슈 대응 시 혼동하지 않도록 팀 내에서 두 명령어의 차이를 사전에 공유해두는 게 좋다.
- 기능 플래그(feature flag)로 관리하는 미공개 기능이 있다면, 해당 플래그 이름과 기능명이 배포 코드에 그대로 노출될 수 있다는 점을 인지해야 한다. 민감한 로드맵 정보는 코드에서 분리하거나, 서버 사이드에서만 관리하고 클라이언트 번들에는 포함하지 않는 구조를 고려해볼 수 있다.
- 사용자 입력을 로깅하는 로직이 있다면, 어떤 조건에서 무엇을 로깅하는지가 코드에 드러날 경우 사용자 신뢰 문제로 이어질 수 있다. 로깅 정책은 공개 문서나 프라이버시 정책에 명시하고, 코드 내 감지 패턴이 외부에 노출되지 않도록 서버 사이드로 이전하는 것을 검토해볼 만하다.
Terminology
source map압축/난독화된 JavaScript 파일을 원본 소스코드로 역추적할 수 있게 해주는 파일. 개발 디버깅용이지만 프로덕션 배포에 포함되면 내부 코드가 그대로 노출된다.
npm deprecateNPM 패키지 특정 버전을 '더 이상 쓰지 말라'고 표시하는 명령어. 파일은 레지스트리에 그대로 남아 다운로드 가능하며, 실제로 삭제하려면 npm unpublish를 써야 한다.
feature flag코드 배포 없이 특정 기능을 켜고 끌 수 있게 하는 설정값. 미공개 기능을 코드에 먼저 넣어두고 나중에 플래그만 활성화해서 출시할 때 사용한다.
distillation (모델 증류)크고 강력한 모델(teacher)의 출력 데이터를 학습 데이터로 활용해 작은 모델(student)을 훈련시키는 기법. 여기서는 Claude Code의 API 응답을 스크래핑해서 경쟁 모델을 학습시키는 행위를 가리킨다.
cyclomatic complexity코드의 복잡도를 측정하는 지표로, 조건문·반복문 등 분기점이 많을수록 숫자가 높아진다. 일반적으로 10 이하를 권장하며, 486은 유지보수가 거의 불가능한 수준이다.
anti-distillation경쟁사가 자사 모델의 API 응답을 학습 데이터로 수집하지 못하도록 응답에 가짜 정보를 섞어 데이터를 오염시키는 방어 기법.
Related Resources
- https://twitter.com/Fried_rice/status/2038894956459290963
- https://www.npmjs.com/package/@anthropic-ai/claude-code/v/2
- https://github.com/chatgptprojects/claude-code
- https://github.com/instructkr/claude-code/blob/main/src/constants.ts
- https://daveschumaker.net/digging-into-the-claude-code-source-code/
- https://news.ycombinator.com/item?id=43173324
- https://claudebuddychecker.netlify.app/
- https://malus.sh/