본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 21. 02:19

10,000개의 악성 GitHub 저장소: AI 의존성 제안이 보안 위험이 된 이유

요약

AI 코딩 도구가 학습한 GitHub 데이터 내에 10,000개 이상의 악성 저장소가 포함되어 보안 위협을 초래하고 있습니다. 타이포스쿼팅, 의존성 혼동, 스타 파밍 등의 기법을 통해 악성 패키지가 유포되고 있어 개발자의 주의가 필요합니다.

핵심 포인트

  • 10,000개 이상의 악성 GitHub 저장소가 트로이 목마 멀웨어를 유포 중
  • 타이포스쿼팅 및 의존성 혼동을 이용한 정교한 공격 기법 사용
  • AI 코딩 도구가 학습한 데이터에 악성 코드가 포함되어 위험성 증대
  • 패키지 설치 시 라이프사이클 훅을 통한 자동 악성 스크립트 실행 주의

이 기사는 원래 LucidShark Blog에 게시되었습니다.

보안 연구원들은 최근 AI 코딩 도구를 사용하는 모든 개발자가 즉시 멈춰 서서 확인해야 할 발견을 공개했습니다. 10,000개 이상의 GitHub 저장소가 Trojan(트로이 목마) 멀웨어(malware)를 활발히 유포하고 있다는 사실입니다. 이 저장소들은 합법적으로 보이도록 설계되었으며, 실제 패키지 이름을 사용하고, 대충 훑어보는 검사(casual inspection)를 통과합니다. 이 숫자는 여러분이 생각하는 것보다 더 중요합니다. 왜냐하면 여러분의 AI 코딩 도구가 GitHub를 기반으로 학습되었기 때문입니다.

악성 저장소 문제 (The Malicious Repo Problem)

연구원들이 기록한 이 캠페인은 보안 커뮤니티가 단일 조정된 물결 속에서 이전에 본 적 없는 규모로 작동합니다. 공격자들은 도달 범위를 극대화하기 위해 세 가지 중첩된 기술을 사용합니다:

  • 타이포스쿼팅 (Typosquatting): 인기 있는 라이브러리와 이름이 한 글자 차이 나는 저장소 및 패키지 (예: requests 대신 reqeusts, colors 대신 coloers). 인간의 눈은 글자 위치가 바뀐 것을 그냥 지나치기 쉽습니다.
  • 의존성 혼동 (Dependency confusion): 패키지 관리자가 범위 충돌(scope conflicts)을 해결하는 방식을 악용하여, 내부 프라이빗 패키지와 동일한 이름의 퍼블릭 패키지를 업로드하는 방식입니다. 만약 여러분의 레지스트리(registry)가 프라이빗보다 퍼블릭을 먼저 확인한다면, 공격자가 승리하게 됩니다.
  • 스타 파밍 (Star-farming) 및 사회적 증거 (social proof): GitHub 스타(star)를 구매하고, 합법적인 README 콘텐츠를 복제하며, 설득력 있는 커밋(commit) 이력을 유지하는 방식입니다. 이러한 저장소들은 언뜻 보기에 건강한 오픈 소스 프로젝트와 구별할 수 없습니다.

Trojan 페이로드(payload)는 일반적으로 설치 라이프사이클 훅(install lifecycle hooks)인 preinstall, postinstall 또는 prepare에 내장됩니다. 여러분이 npm install 또는 pip install을 실행하는 순간, 악성 스크립트가 실행됩니다. 이는 환경 변수(environment variables)를 유출하거나, 지속성(persistence)을 확보하거나, 명령 및 제어(command-and-control) 서버로 비콘(beacon)을 보낼 수 있습니다. 예상치 못한 네트워크 트래픽을 발견했을 때는 이미 피해가 발생한 후일 것입니다.

경고: npm 및 PyPI 패키지의 라이프사이클 훅 (Lifecycle hooks)은 설치 중에 자동으로 실행됩니다. 별도의 확인 프롬프트는 없습니다. 만약 의존성 (dependency)이 악성이라면, 패키지 매니저 (package manager)가 이를 해결(resolve)하는 즉시 페이로드 (payload)가 실행됩니다.

AI 코딩 도구가 상황을 악화시키는 이유

AI 코드 어시스턴트 (AI code assistants)가 작동하는 방식에 대한 불편한 진실은 다음과 같습니다. Claude Code, Cursor, GitHub Copilot 및 기타 모든 AI 코딩 도구는 GitHub를 포함한 인터넷상의 코드를 통해 제안 방식을 학습했습니다. 모델이 사용자의 함수 시그니처 (function signature)를 보고 임포트 (import)를 제안할 때, 이는 수백만 개의 학습 예시를 바탕으로 패턴 매칭 (pattern-matching)을 수행하는 것입니다. 그 예시 중 일부는 합법적인 패키지를 임포트했습니다. 일부는 나중에 침해된 패키지를 임포트했습니다. 또 다른 일부는 처음부터 악의적이었던 저장소 (repos)에서 패키지를 임포트했습니다.

문제는 AI 도구가 의도적으로 멀웨어 (malware)를 제안한다는 것이 아닙니다. 문제는 구조적인 것입니다:

  • AI 제안은 암묵적인 권위를 가집니다. 개발자들은 자동 완성 (autocomplete)을 신뢰하도록 훈련되어 왔습니다. IDE가 import colorama from 'coloarma'를 제안하면, 대부분의 개발자는 npm 레지스트리 (npm registry)를 수동으로 확인하지 않고 이를 수용합니다.
  • '수락 후 진행'하는 워크플로 (workflow)는 정밀 조사를 우회합니다. AI 코딩 도구의 전체 UX (User Experience)는 몰입 상태 (flow state)를 유지하도록 최적화되어 있습니다. 수락을 위해 Tab, 수락을 위해 Tab, 수락을 위해 Tab을 누릅니다. 임포트를 감사 (audit)하기 위해 멈추는 것은 그 리듬을 깨뜨리며, 대부분의 개발자는 멈추지 않습니다.
  • AI 제안은 Stack Overflow 답변보다 더 권위 있게 보입니다. Stack Overflow의 사람이 패키지를 제안하면, 사용자는 링크를 클릭하여 다운로드 수를 확인할 수도 있습니다. 하지만 Claude Code가 에디터 내에서 인라인 (inline)으로 제안하면, 패키지 이름은 그저... 그곳에 있습니다. 수락할 준비가 된 채로 말입니다.
  • AI 도구는 패키지의 존재 여부나 무결성을 검증하지 않습니다. 주요 AI 코딩 어시스턴트 중 그 어떤 것도 제안을 제시하기 전에, 제안된 패키지가 실제인지, 침해되지 않았는지, 또는 알려진 악성 행위자가 아닌지 확인하기 위해 패키지 레지스트리 (package registry)에 쿼리 (query)를 보내지 않습니다.

경고 (Warning): AI 코딩 도구는 실시간 레지스트리 확인 (registry checks)을 수행하지 않습니다. 합법적인 임포트 (import)처럼 보이는 제안이라도, 모델이 오염된 학습 데이터로부터 학습한 타이포스쿼팅 (typosquatted) 또는 악성 패키지를 참조할 수 있습니다.

그 결과, 5년 전에는 존재하지 않았던 위협 모델 (threat model)이 등장했습니다. AI 코딩 도구가 등장하기 전에는 개발자들이 임포트를 수동으로 입력했으며, 무엇을 추가하는지에 대해 최소한 조금 더 신중했습니다. 당시의 번거로움 (friction)은 하나의 기능이었습니다. AI 코딩 도구는 그 번거로움을 완전히 제거했으며, 그 과정에서 의존성 수용 파이프라인 (dependency ingestion pipeline) 내에 존재하는 몇 안 되는 인간 체크포인트 중 하나를 제거했습니다.

귀하의 코드베이스가 이미 수락한 AI 제안들

AI 코딩 도구를 몇 주 이상 사용해 왔다면, 최소한 하나 이상의 의존성 제안을 감사 (auditing) 없이 수락했을 가능성이 높습니다. 귀하의 코드베이스에 무엇이 있는지 확인하는 방법은 다음과 같습니다.

1단계: 최근에 추가된 임포트 찾기

`# 지난 30일 동안 git log를 통해 추가된 모든 임포트 찾기
git log , since="30 days ago" , diff-filter=A -p ,  "*.js" "*.ts" "*.py" "*.go"   | grep "^+"   | grep -E "(import|require|from)"   | sort -u`

2단계: 전체 의존성 목록 추출하기

`# Node.js 프로젝트의 경우
cat package.json | python3 -c "
import json, sys
...

3단계: 알려진 악성 패키지 목록에 대해 SCA 실행하기

`# OSV (Open Source Vulnerabilities) 데이터베이스를 통해 각 패키지 확인
while IFS= read -r pkg; do
  pkg_name=$(echo "$pkg" | cut -d'@' -f1 | cut -d'=' -f1)
...

레이어 2: GitHub Actions SCA 워크플로우

`# .github/workflows/sca.yml
name: Supply Chain Audit

...

레이어 3: Claude Code를 위한 MCP 통합 패턴

이 지점이 LucidShark가 직접적으로 연결되는 부분입니다. 커밋 (commit) 시점까지 기다리는 대신, 의존성이 디스크에 기록되기도 전에 Claude Code 세션 내부에서 SCA 결과를 노출할 수 있습니다.

`# lucidshark.config.yaml
checks:
  sca:
...

공급망 게이트 (Supply Chain Gate)에서 LucidShark의 역할

LucidShark는 복잡도 분석 (complexity analysis), 테스트 커버리지 (test coverage), 결합도 지표 (coupling metrics), 중복 탐지 (duplication detection)와 함께 내장된 체크 항목 중 하나로 SCA를 실행합니다. 모든 것을 로컬에서 실행하기로 한 설계 결정은 특히 공급망 위험 (supply chain risk) 측면에서 중요합니다. 클라우드 기반 스캐너를 실행하면 소프트웨어의 공격 표면 (attack surface) 전체를 나타내는 의존성 매니페스트 (dependency manifest)가 사용자의 머신을 떠나게 됩니다. 로컬 실행은 도구 자체로부터의 데이터 유출 (data exfiltration) 위험이 전혀 없음을 의미합니다.

MCP 통합을 통해 Claude Code는 SCA 탐지 결과를 인라인 (inline)으로 표시할 수 있습니다. 만약 Claude Code에 의존성을 추가하도록 요청했는데 해당 패키지에 알려진 취약점 (vulnerabilities)이 있다면, MCP 도구 호출은 package.json이 수정되기 전에 해당 탐지 결과를 반환합니다. 이 게이트 (gate)는 사후에 덧붙여진 것이 아니라 워크플로 (workflow) 내에 존재합니다.

일반적인 프로젝트에서 체크는 60초 이내에 완료됩니다. 매일 AI가 생성한 코드를 배포하는 팀에게 이는 악성 임포트 (malicious import)가 프로덕션에 도달하기 전에 잡아내느냐, 아니면 사후 분석 (post-mortem) 보고서에서 사고 소식을 읽느냐의 차이입니다.

참고: LucidShark의 SCA 체크는 OSV.dev를 쿼리하고 GitHub Advisory Database를 완전히 로컬에서 교차 참조합니다. 스캔 중에 의존성 이름, 매니페스트 내용 또는 소스 코드가 사용자의 머신을 떠나지 않습니다.

10,000개의 악성 저장소 이야기는 단발적인 사건이 아닙니다. 이는 AI 코딩 시대에 맞춰 특별히 적응한, 성숙해가는 공격자의 플레이북 (attacker playbook)을 보여주는 증거입니다. 공격자들은 AI 도구를 사용하는 개발자들이 코드를 감사 (audit)하는 것보다 제안을 더 빠르게 수용한다는 점을 알고 있습니다. 그들은 바로 그러한 행동을 악용하기 위해 대규모 인프라를 구축하고 있습니다. 방어책은 코딩 속도를 늦추는 것이 아닙니다. 공격보다 더 빠르게 실행되는 자동화되고 결정론적인 (deterministic) 체크를 삽입하는 것입니다.

LucidShark 체험하기: npm을 통해 설치하고 (npm install -g lucidshark), 저장소에서 lucidshark analyze를 실행하면 60초 이내에 복잡도, 커버리지, 결합도 지표와 함께 SCA 결과를 확인할 수 있습니다. 완전히 로컬에서 실행되어 데이터가 머신을 떠나지 않으며, MCP를 통해 Claude Code와 통합됩니다. lucidshark.com

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0