AI 코딩 패키지 환각: 없는 라이브러리 설치를 막는 법
AI가 작성한 코드를 실행했는데 패키지를 찾을 수 없다는 오류가 뜨거나, 설치는 됐지만 전혀 다른 기능을 가진 라이브러리가 내려받아지는 경우가 있습니다. 이 문제는 단순한 오타가 아니라 AI 코딩 패키지 환각일 수 있습니다. 모델이 실제로 존재하지 않는 패키지 이름을 그럴듯하게 만들거나, 오래된 사용법과 현재 API를 섞어 제안하는 현상입니다.
더 위험한 상황은 누군가 그 가짜 이름으로 악성 패키지를 먼저 등록했을 때입니다. 개발자는 AI의 답변을 믿고 설치 명령을 실행하지만, 결과적으로 공급망 공격의 입구를 직접 열게 됩니다. 아래에서는 오류를 빠르게 구분하고 안전한 의존성만 프로젝트에 넣는 절차를 단계별로 설명합니다.
설치 오류가 나면 패키지 이름부터 의심합니다
환각과 단순 환경 오류를 구분하는 신호
npm install, pip install 또는 poetry add가 실패했다고 해서 모두 AI 환각은 아닙니다. 네트워크 장애, 사설 저장소 인증 만료, 런타임 버전 불일치도 비슷한 메시지를 만듭니다. 먼저 오류 문구에서 패키지를 찾지 못했다는 의미인지, 패키지는 있지만 현재 환경과 맞지 않는다는 의미인지 나눠야 합니다.
예를 들어 npm의 404 오류나 pip의 “No matching distribution found”는 이름, 저장소, 지원 버전을 확인하라는 신호입니다. 반면 빌드 휠 생성 실패나 네이티브 모듈 컴파일 오류는 패키지가 실제로 존재하더라도 발생합니다. AI가 제안한 이름을 한 글자씩 바꾸며 무작정 재설치하면 이름이 비슷한 엉뚱한 패키지를 선택할 가능성만 커집니다.
- 존재 여부: 공식 패키지 저장소에서 정확한 이름을 직접 검색합니다.
- 배포 이력: 최초 등록일과 최신 배포일, 버전 간격을 확인합니다.
- 프로젝트 연결: 저장소와 공식 문서가 동일한 패키지를 가리키는지 봅니다.
- 환경 조건: Node.js, Python, 운영체제 및 CPU 아키텍처 지원 범위를 확인합니다.
- 오류 재현: 기존 프로젝트가 아닌 비어 있는 임시 환경에서 같은 설치를 시험합니다.
빠른 판단 기준: AI가 패키지 이름은 말하면서 공식 문서, 저장소 주소, 정확한 버전을 제시하지 못한다면 설치보다 검증이 먼저입니다.
특히 이름이 지나치게 구체적이면서 검색 결과가 거의 없다면 경계해야 합니다. “프레임워크명-기능명-helper”처럼 자연스러운 조합은 사람이 보기에는 타당하지만 실제 패키지가 아닐 수 있습니다. 검색 결과에 블로그의 복사된 코드만 반복되고 공식 배포 페이지가 없다면 존재가 확인될 때까지 설치하지 않는 것이 안전합니다.
공식 저장소에서 네 가지 흔적을 대조합니다
다운로드 수보다 중요한 검증 항목
패키지 페이지가 존재한다는 사실만으로는 충분하지 않습니다. 공격자는 AI가 자주 만들어 내는 이름을 관찰한 뒤 같은 이름으로 패키지를 등록할 수 있습니다. 따라서 관리자, 소스 저장소, 문서, 배포 시점이라는 네 가지 흔적이 서로 일치하는지 확인해야 합니다. 하나라도 연결이 끊기면 설치를 보류하는 편이 좋습니다.
다운로드 수는 참고 자료일 뿐 안전 보증서가 아닙니다. 정상적인 신규 라이브러리는 다운로드가 적을 수 있고, 반대로 자동화된 다운로드 때문에 의심스러운 패키지의 수치가 커질 수도 있습니다. 프로젝트 홈페이지에서 공식 설치 명령을 찾아 패키지 저장소의 표기와 대조하고, GitHub 등의 소스 저장소에서는 릴리스 태그와 배포 버전이 대응하는지 살펴보세요.
| 확인 대상 | 정상에 가까운 신호 | 주의할 신호 |
|---|---|---|
| 관리자 | 공식 조직 또는 알려진 유지관리자 | 생성된 지 얼마 안 된 단일 계정 |
| 소스 저장소 | 배포 파일과 태그가 연결됨 | 링크가 없거나 전혀 다른 프로젝트 |
| 문서 | 설치법과 API 예제가 현재 버전과 일치 | README가 짧고 설명이 모호함 |
| 배포 기록 | 변경 내역과 릴리스 간격이 자연스러움 | 모든 버전이 하루에 집중됨 |
- AI 답변에서 패키지의 정확한 철자와 제안 버전을 분리해 적습니다.
- npm, PyPI, Maven Central 등 해당 생태계의 공식 저장소에서 직접 검색합니다.
- 공식 프로젝트 문서가 안내하는 설치 명령과 이름이 같은지 비교합니다.
- 압축 파일에 포함될 파일 목록과 설치 스크립트의 존재 여부를 확인합니다.
- 조직 내부에서 이미 승인된 대체 패키지가 있는지 의존성 목록을 조회합니다.
코드와 데이터가 어떤 방식으로 보호 대상이 되는지 배경을 파악하려면 코드 보안 관련 지식백과 설명도 참고할 수 있습니다. 다만 용어를 이해하는 것과 특정 오픈소스 패키지의 안전성을 판정하는 것은 별개이므로, 실제 설치 전에는 프로젝트별 흔적을 다시 확인해야 합니다.
설치 전 격리 환경에서 동작을 관찰합니다
내 컴퓨터보다 일회용 환경이 먼저입니다
존재가 확인된 패키지도 곧바로 업무용 노트북이나 운영 프로젝트에 설치하지 않는 것이 좋습니다. 설치 과정에서는 네트워크 요청, 셸 명령 실행, 환경 변수 조회, 파일 생성이 일어날 수 있기 때문입니다. 컨테이너나 일회용 가상환경에서 먼저 실행하면 문제가 생겨도 영향 범위를 크게 줄일 수 있습니다.
Python이라면 새 가상환경을 만들고 최소 권한의 사용자로 설치합니다. Node.js에서는 빈 디렉터리에 새 프로젝트를 만든 뒤 잠금 파일의 변화를 확인하세요. 가능하다면 설치 스크립트를 비활성화한 상태로 패키지를 내려받아 구성 파일을 먼저 읽습니다. npm의 경우 생명주기 스크립트가 무엇을 실행하는지 확인한 후 필요한 경우에만 허용하는 방식이 실용적입니다.
- 빈 환경 생성: 기존 인증 정보나 프로젝트 파일이 들어 있지 않은 작업 공간을 준비합니다.
- 버전 고정:
latest대신 검증할 정확한 버전을 지정합니다. - 스크립트 관찰: 설치 전후 실행 명령과 새로 생성된 파일을 비교합니다.
- 통신 제한: 꼭 필요한 저장소 외의 네트워크 연결은 차단하거나 기록합니다.
- 정적 검사: 난독화된 코드, 외부 바이너리 다운로드, 자격 증명 탐색 코드를 찾습니다.
- 기능 시험: AI가 약속한 핵심 API가 실제 문서대로 동작하는지 작은 예제로 확인합니다.
설치 직후 홈 디렉터리, 셸 설정, SSH 키 경로 또는 클라우드 인증 폴더에 변화가 생겼다면 정상 기능 여부와 관계없이 조사를 중단해야 합니다. 테스트 환경에는 실제 API 키를 넣지 말고 값이 없는 가짜 변수를 사용하세요. 패키지가 실행에 필요한 비밀정보를 과도하게 요구하는지도 중요한 평가 기준입니다.
격리 환경은 악성 여부를 자동으로 판정하는 장치가 아닙니다. 관찰할 수 있는 흔적을 늘리고 사고의 범위를 줄이는 안전벨트로 이해하는 편이 정확합니다.
검증이 끝나면 환경을 그대로 재사용하지 말고 폐기하는 것이 좋습니다. 단순히 패키지를 삭제해도 설치 스크립트가 만든 예약 작업이나 숨김 파일이 남을 수 있기 때문입니다. 팀에서는 같은 절차를 반복할 수 있도록 컨테이너 설정과 검사 명령만 코드로 보관하고, 테스트 결과에는 패키지명·버전·해시·검사 날짜를 기록해 두세요.
AI 프롬프트와 의존성 정책을 함께 고칩니다
모델에게 검증 가능한 답을 요구하는 방식
AI에게 “이 기능을 구현해 줘”라고만 요청하면 모델은 코드 완성을 우선하며 익숙해 보이는 패키지를 조합할 수 있습니다. 프롬프트에 새 의존성 추가 금지, 공식 문서 근거 제시, 기존 잠금 파일 우선 같은 제약을 넣으면 불필요한 추천을 줄일 수 있습니다. 중요한 점은 AI의 자신감 있는 설명을 검증 결과로 착각하지 않는 것입니다.
예를 들어 “현재 package.json에 있는 라이브러리만 사용하고, 불가능하면 코드를 만들지 말고 이유를 설명해 달라”고 요청해 보세요. 신규 패키지가 꼭 필요하다면 공식 저장소 주소, 유지관리 주체, 최소 지원 버전, 라이선스, 대체재를 함께 제시하게 합니다. 링크를 받았더라도 사람이 직접 도메인과 프로젝트 연결 관계를 확인해야 합니다.
- “새 패키지를 임의로 추가하지 말고 표준 라이브러리 대안을 먼저 제시해 주세요.”
- “추천한 패키지의 공식 문서에서 확인해야 할 API 이름과 버전을 적어 주세요.”
- “설치 명령과 코드 변경을 분리하고, 승인 전에는 설치 명령을 실행하지 마세요.”
- “잠금 파일을 읽고 현재 사용 중인 버전에서 가능한 구현인지 판단해 주세요.”
- “확실하지 않은 패키지명은 추측하지 말고 확인 불가라고 표시해 주세요.”
팀 저장소에서 자동으로 막는 장치
개인의 주의력만으로 모든 의존성 문제를 막기는 어렵습니다. pull request에서 manifest와 잠금 파일 변경을 별도 항목으로 표시하고, 승인된 관리자가 검토하도록 규칙을 두세요. 새 패키지가 추가되면 라이선스, 알려진 취약점, 설치 스크립트, 출처를 자동 검사하되 자동 점수 하나만으로 승인하지는 않아야 합니다.
코드 보안의 주요 개념처럼 보안은 한 번의 검사보다 변경 과정 전반의 통제가 중요합니다. 특히 AI 코딩 도구가 터미널 실행 권한까지 갖고 있다면 “코드 제안”과 “패키지 설치”의 승인 단계를 분리하세요. 개발자가 diff를 읽기 전에 에이전트가 설치까지 완료하는 흐름은 편하지만 문제 패키지가 내부망에 접근할 시간도 함께 제공합니다.
- 새 의존성이 포함된 변경은 일반 코드 리뷰와 분리해 눈에 띄게 표시합니다.
- manifest뿐 아니라 잠금 파일에서 실제 내려받는 주소와 무결성 값을 확인합니다.
- 조직이 허용한 패키지와 금지한 패키지를 중앙 정책으로 관리합니다.
- 자동 업데이트 도구도 메이저 버전과 신규 패키지는 사람의 승인을 거치게 합니다.
- 승인 근거와 검증한 버전을 기록해 다음 업데이트 때 비교 자료로 사용합니다.
비공개 저장소와 이름 충돌은 별도 경로로 다룹니다
모든 미발견 오류가 환각은 아닙니다
공식 공개 저장소에서 검색되지 않는다는 이유만으로 패키지가 가짜라고 단정할 수는 없습니다. 회사가 사설 npm 레지스트리나 Python 인덱스에만 배포한 내부 패키지일 수 있고, 특정 운영체제에서만 제공되는 의존성일 수도 있습니다. 이때는 AI에게 재차 이름을 추측하게 하기보다 저장소 설정과 조직 문서를 확인해야 합니다.
더 까다로운 예외는 내부 패키지와 공개 패키지의 이름이 같은 경우입니다. 패키지 관리자의 저장소 우선순위가 잘못 설정되면 의도했던 내부 버전 대신 공격자가 공개 저장소에 올린 동명 패키지가 선택될 수 있습니다. 이른바 의존성 혼동 위험을 줄이려면 내부 패키지에 고유한 네임스페이스를 쓰고, 패키지별 출처를 명시적으로 고정해야 합니다.
- 사설 패키지: 담당 팀, 내부 문서, 배포 파이프라인에서 존재를 확인합니다.
- 동일 이름: 공개 저장소와 내부 저장소의 버전 번호 및 우선순위를 비교합니다.
- 미러 저장소: 원본과 동기화 시점이 달라 최신 버전이 아직 없을 수 있습니다.
- 플랫폼 전용 배포: 지원 운영체제와 아키텍처에 맞는 파일이 있는지 확인합니다.
- 폐기된 프로젝트: 패키지가 존재해도 유지보수 종료 여부와 대체 경로를 조사합니다.
또한 정상 패키지라도 유지관리자 계정 탈취, 악성 업데이트, 빌드 시스템 침해까지 이 글의 절차만으로 완전히 판별할 수는 없습니다. 고위험 서비스라면 서명 검증, 소프트웨어 자재 명세서, 재현 가능한 빌드, 네트워크 격리처럼 더 강한 통제가 필요합니다. 금융·의료·공공 시스템에서는 조직의 보안 담당자와 별도 승인 기준을 마련해야 합니다.
반대로 사내 실험용 코드에 지나치게 무거운 절차를 적용하면 개발자가 검증을 우회할 수 있습니다. 데이터 민감도와 배포 범위에 따라 단계를 조절하되, 출처 확인·정확한 버전 고정·잠금 파일 검토라는 최소선은 남겨 두세요. AI가 생성한 이름을 사람이 공식 경로에서 확인할 수 없다면 그 패키지를 쓰지 않고, 표준 라이브러리나 검증된 대체재로 설계를 바꾸는 판단도 충분히 좋은 해결책입니다.

- 다음글AI 코딩 에이전트는 Git 워크트리로 써야 충돌이 사라진다 26.09.01
등록된 댓글이 없습니다.
