Dev/AI

macOS에서 'codex'가 사용자의 컴퓨터를 손상시킵니다 경고 해결하기

develophil 2026. 5. 21. 10:50
반응형

 

 

어느 날 갑자기 OpenAI Codex CLI가 macOS에서 "'codex'은(는) 사용자의 컴퓨터를 손상시킵니다. 해당 항목을 휴지통으로 이동해야 합니다." 라는 경고와 함께 실행이 차단되는 현상이 발생했다. 결론부터 말하면 PC가 감염된 게 아니라, OpenAI의 macOS 코드 서명 인증서가 폐기되면서 Gatekeeper가 구 버전 바이너리를 차단한 것이다.

  • 원인: 2026년 5월 8일자로 OpenAI macOS 코드 서명 인증서 폐기 (axios npm 공급망 공격 여파)
  • 영향 받는 앱: ChatGPT Desktop, Codex, Codex CLI, Atlas
  • 해결: 최신 버전으로 재설치 → npm install -g @openai/codex@latest (npm 설치 기준)
  • 휴지통으로 옮기지 말고 "취소" 누른 뒤 재설치하면 끝

증상

두 가지 형태로 나타난다.

1) 앱 첫 실행 시 macOS 경고 팝업

  • "'codex'은(는) 사용자의 컴퓨터를 손상시킵니다. 해당 항목을 휴지통으로 이동해야 합니다."
  • 버튼 두 개: 휴지통으로 이동 / 취소
  • 하단 체크박스: "다른 사용자를 보호하기 위해 악성코드를 Apple에 보고"
주의: 휴지통으로 이동 누르지 말 것. 하단의 "악성코드를 Apple에 보고" 체크박스도 해제하자. 실제 악성코드가 아니라 인증서 폐기 때문이다.

2) 터미널에서 SIGKILL

❯ codex --version
[1]    11530 killed     codex --version

프로세스가 시작과 동시에 killed 되며, 어떤 출력도 없이 종료된다. 이게 바로 Gatekeeper가 폐기된 인증서로 서명된 바이너리를 강제 종료시킨 흔적이다.

원인: axios 공급망 공격과 인증서 폐기

2026년 3월 31일, npm의 axios 라이브러리(주당 1억 다운로드 규모)가 공급망 공격을 당했다. 공격자는 메인테이너 계정을 탈취해 악성 버전(1.14.1 / 0.30.4)을 푸시했고, 이 버전이 OpenAI의 GitHub Actions macOS 앱 서명 워크플로우에 자동으로 끌려 들어갔다.

해당 워크플로우는 ChatGPT Desktop, Codex, Codex CLI, Atlas의 코드 서명 인증서와 notarization 자료에 접근 권한이 있었다. OpenAI는 분석 결과 인증서가 실제로 유출되지는 않았다고 결론 내렸지만, 보안 차원에서 구 인증서를 폐기하고 신규 인증서로 교체하기로 결정했다.

이 폐기가 적용된 날이 2026년 5월 8일이다. 그 이후로 구 인증서로 서명된 빌드는 macOS Gatekeeper가 실행을 거부한다.

안전한 빌드 기준: 2026년 4월 20일 이후 빌드는 새 인증서로 서명되어 있다. codex --version이 정상 출력되면 새 인증서 빌드다.

해결 과정

Step 1. Codex가 어떻게 설치됐는지 확인

which codex
# → /opt/homebrew/bin/codex

ls -l /opt/homebrew/bin/codex
# → /opt/homebrew/bin/codex -> ../lib/node_modules/@openai/codex/bin/codex.js

심볼릭 링크가 node_modules로 연결돼 있으면 npm 글로벌 설치다. /opt/homebrew 경로에 있다고 무조건 Homebrew는 아니라는 점이 헷갈리기 쉽다. Apple Silicon에서 brew로 깐 node를 쓰면 npm 글로벌 prefix가 /opt/homebrew가 되기 때문이다.

설치 경로별 매핑:

경로 / 단서 설치 방식 재설치 명령
node_modules/@openai/codex 로 심볼릭 npm 글로벌 npm install -g @openai/codex@latest
brew list --formula | grep codex 에 잡힘 Homebrew formula brew reinstall codex
brew list --cask | grep codex 에 잡힘 Homebrew cask brew reinstall --cask codex
위 어디에도 없음 직접 다운로드한 바이너리 파일 삭제 후 공식 사이트에서 재다운로드

Step 2. npm 글로벌 패키지 확인

npm list -g --depth=0 2>/dev/null | grep -i codex
# → ├── @openai/codex@0.115.0

버전이 0.115.0 이고 설치일이 3월 17일이었다. 즉, 인증서 폐기(5/8) 이전 빌드라 차단당한 것이다.

Step 3. 최신 버전으로 재설치

npm install -g @openai/codex@latest

codex --version
# → codex-cli 0.132.0

killed 없이 버전이 정상 출력되면 성공. Gatekeeper 차단도 자동으로 풀린다.


Troubleshooting

1) brew update에서 "Repository not found" 에러

오래된 tap이 GitHub에서 사라진 경우 발생한다. 대표적인 케이스:

Error: homebrew/homebrew-cask-fonts does not exist!
homebrew/homebrew-cask-versions does not exist!

cask-fonts, cask-versions는 메인 homebrew/cask로 통합되면서 없어진 tap들이다. 그냥 정리하면 된다.

brew untap homebrew/homebrew-cask-fonts
brew untap homebrew/homebrew-cask-versions

2) untap이 거부되는 경우 (formula 의존성)

Error: Refusing to untap wn/tap because it contains the following installed formulae or casks:
gitignore

해당 tap에서 깐 formula가 남아있어서 거부된다. 두 가지 선택:

  • 해당 formula도 같이 제거: brew uninstall <formula명> && brew untap <tap명>
  • 유지하되 무시: 로컬 바이너리는 동작하므로 brew update가 매번 에러 뱉는 것만 감수

3) 재설치 후에도 killed가 뜨는 경우

npm 캐시가 구버전을 그대로 쓰거나, quarantine 속성이 남아있을 수 있다.

# 캐시 클리어 후 완전 재설치
npm uninstall -g @openai/codex
npm cache clean --force
npm install -g @openai/codex@latest

# quarantine 속성 제거
xattr -dr com.apple.quarantine $(npm root -g)/@openai/codex
codex --version

4) which codex/opt/homebrew/bin인데 brew list에는 안 잡힘

npm 글로벌 설치인데 brew로 깐 node의 prefix가 /opt/homebrew여서 헷갈리는 경우다. ls -l로 심볼릭 링크 대상을 확인해서 node_modules로 가면 npm 설치다.

5) ExperimentalWarning 메시지가 같이 뜨는 경우

(node:19525) ExperimentalWarning: CommonJS module ... is loading ES Module ...
Support for loading ES Module in require() is an experimental feature

Node.js 자체의 일반 경고로 codex와 무관하다. 동작에 영향 없으니 무시해도 된다.


마무리

이 이슈는 본인 PC에 문제가 있는 게 아니라 OpenAI 쪽 인증서 폐기로 발생한 시스템적 문제다. 따라서:

  • 다른 머신도 점검: 메인 데스크탑, 노트북, 홈서버 등 codex가 깔린 모든 머신에서 동일하게 발생한다. 미리 일괄 업그레이드 추천.
  • 다른 OpenAI 앱도 확인: ChatGPT Desktop, Atlas 브라우저 등 5/8 이전 빌드면 모두 같은 증상이 난다. 인앱 업데이트가 이미 막혔으므로 공식 사이트에서 새로 받아야 한다.
  • 장기적 시사점: CI/CD에 서명 권한이 묶여 있는 환경에서는 의존성 핀 고정(minimumReleaseAge 설정, 플로팅 태그 대신 커밋 해시 사용)이 사고를 막는 가장 기본적인 방어선이다.

참고로 이번 사고가 거의 운으로 막힌 케이스라는 점은 한 번 짚어둘 만하다. 페이로드 실행 타이밍과 인증서 주입 시퀀스가 살짝만 달랐어도 실제 인증서 유출까지 갈 수 있는 상황이었다. 본인 프로젝트의 GitHub Actions에서 외부 의존성을 끌어다 쓰는 부분이 있다면 한 번 점검해보는 계기로 삼으면 좋겠다.

반응형

'Dev > AI' 카테고리의 다른 글

[AI 트렌드] 2026.05.23  (1) 2026.05.23
[AI 트렌드] 2026.05.22  (0) 2026.05.22
[AI 트렌드] 2026.05.21  (0) 2026.05.21
[AI 트렌드] 2026.05.20  (0) 2026.05.20
티스토리 블로그 네이버 서치어드바이저 연동 방법 완벽 가이드  (0) 2026.05.19