I Point a Local LLM at Every Repo Before Opening It in My Editor
개요
알 수 없는 저장소를 로컬 LLM으로 먼저 분석하여 코드 실행 없이 잠재적인 악성 페이로드를 탐지하는 워크플로우가 소개된다.
주요 내용
* 공격 벡터: 웹3 채용 프로젝트의 README와 Next.js 구조 등은 정상적으로 보이지만, postinstall 스크립트 등을 통해 Base64로 인코딩된 페이로드를 다운로드하는 방식의 공격이 일반적이다. 이러한 페이로드는 .src 폴더가 아닌 lifecycle scripts, config files, utils 파일 등에 숨겨져 있는 경우가 많다.
* 안전한 파일 접근: 저장소를 열기 전에 코드를 실행하거나 설치하지 않기 위해 --no-checkout 옵션으로 클론 후 git ls-tree -r HEAD --name-only로 파일 목록만 확인하거나, curl과 tar를 이용해 .tar.gz 파일을 특정 디렉토리(quarantine/)로 압축 해제하는 방식을 사용한다. VS Code와 같이 자동 실행 기능을 가진 에디터 사용은 피한다.
* 기본 점검 (LLM 이전):
* package.json의 install, prepare, prepublish, postpack 스크립트를 검사하여 라이프사이클 스크립트의 악성 여부를 확인한다.
* package.json에 명시된 의존성과 package-lock.json에 명시된 의존성 간의 불일치를 확인하여, 악성 패키지가 설치 시점에 동적으로 로드되는 것을 탐지한다.
* rg 명령어를 사용하여 120자 이상의 Base64 또는 URL 인코딩된 문자열을 탐지한다.
* 로컬 LLM 기반 분석:
* rg로 잠재적인 악성 코드를 포함할 수 있는 파일(child_process, eval, Function, fromCharCode, atob, Buffer.from 등 포함)을 탐지한 후, 로컬 LLM(Ollama, qwen2.5-coder 1.5b 및 7b 모델 사용)을 통해 분석한다.
* LLM 프롬프트는 코드가 무엇을 하는지 요약하는 것이 아니라, 공급망 멀웨어 분석가로서 코드를 평가하여 CLEAN, SUSPICIOUS, MALICIOUS로 분류하고, SIGNALS와 EXPLANATION을 제공하도록 설계된다.
* 분석 시 주요 신호는 다음과 같다: 설치 시점 실행(네트워크 접근, 문자열 디코딩), 매니페스트에 있으나 잠금 파일에 없는 의존성, 인코딩된 데이터와 디코더, 환경 변수 및 민감한 파일(SSH, AWS, 브라우저 프로필, 지갑 등) 접근 시도, 코드 구조의 불균형(일부 파일만 고도로 복잡하거나 난독화됨).
* LLM의 한계 및 고려사항: 1.5b 모델은 일부 난독화된 페이로드를 놓칠 수 있으며, 7b 모델도 고도로 훈련된 공격자는 우회할 수 있다. 완벽한 탐지를 목표로 하기보다는, 시간 소모적이고 대량으로 생성되는 일반적인 공격 시도를 2분 내외로 잡아내는 데 중점을 둔다. 페이로드가 .js 파일에 없을 수도 있으므로 .node 바이너리나 빌드 설정 등 더 넓은 범위의 파일 검사가 필요하다.
시사점
이 워크플로우는 저장소를 열기 전에 로컬 LLM을 활용하여 잠재적인 공급망 공격을 효과적으로 탐지하는 자동화된 방어 기제를 제공하며, 검사 대상 저장소를 직접 실행하지 않으므로 보안 위험을 최소화한다.
댓글
GitHub Discussions