최근 Axios 라이브러리 탈취 사건과 Shai-Hulud 웜의 확산은 충격적입니다. 신뢰하던 메인테이너의 계정이 뚫려 악성 코드가 우리 코드 베이스에 직접 박힐 수 있다는 사실을 증명했으니까요. 보안 팀이 따로 없는 스타트업에게 npm install 한 번으로 AWS 액세스 키가 털리는 상황은 재앙입니다. 하지만 시스템 레벨에 안전망을 깔아두면 악성 스크립트가 실행되어도 데이터가 밖으로 나가는 길을 끊을 수 있습니다.
시스템 레벨에서 데이터 유출 경로 폐쇄하기
공격자가 패키지 설치 시점에 악성 코드를 실행하더라도, 네트워크 수준에서 허용하지 않은 외부 전송을 막으면 자격 증명 유출 피해를 0으로 만들 수 있습니다. AWS 보안 그룹(Security Group)은 기본적으로 모든 아웃바운드 트래픽을 허용합니다. 이건 공격자의 서버로 데이터를 보내라고 고속도로를 깔아준 것이나 다름없습니다.
- 보안 그룹 최소 권한 설정: AWS 콘솔에서 기존 아웃바운드 규칙을 다 지우세요. 서비스 운영에 꼭 필요한 특정 DB 포트와 화이트리스트에 등록된 외부 API 도메인의 IP 대역(443 포트)만 명시적으로 허용하십시오.
- 아웃바운드 프록시 도입: Squid 같은 오픈 소스 프록시를 세워 개발 장비가 외부와 직접 통신하는 통로를 막아야 합니다. Host 헤더나 SNI 정보를 대조해
registry.npmjs.org처럼 승인된 도메인만 통과시킵니다. - 환경 변수 격리:
.env파일은 이제 버리세요. AWS Secrets Manager를 쓰고 애플리케이션 실행 시 SDK로 메모리에만 시크릿을 올리는 계층을 만드십시오.
이렇게 하면 Shai-Hulud 2.0처럼 파일 시스템을 뒤져 .env를 훔치려는 웜의 공격을 물리적으로 무력화합니다.
의존성 무결성 검사 및 버전 고정 자동화
공격은 개발자가 모르는 사이 의존성 트리 안에서 버전이 멋대로 올라갈 때 터집니다. npm install은 유동적인 버전 범위(^1.0.0)를 해결하면서 package-lock.json을 수정할 위험이 큽니다. 패키지 매니저의 무결성 검증 기능을 아주 엄격하게 써야 합니다.
- 엄격한 버전 고정:
.npmrc파일에save-exact=true를 적으세요. 모든 패키지가 캐럿(^) 없이 정확한 버전으로만 저장되도록 강제합니다. - 명령어 교체: 빌드와 배포 스크립트에서
npm install을npm ci로 바꾸십시오.package-lock.json과 조금이라도 다르면 설치를 거부하고 빌드를 즉시 중단시킵니다. - 하위 의존성 강제 교정: Axios v1.14.1처럼 감염된 버전이 이슈가 되면
package.json의overrides필드에"axios": "1.14.0"을 박으세요. 모든 간접 의존성까지 안전한 버전으로 고정됩니다.
npm ci는 기존 node_modules를 밀어버리고 새로 설치하므로 오염된 파일이 남을 틈을 안 줍니다. 의존성 계산을 건너뛰니 빌드 속도가 빨라지는 건 덤입니다.
CI/CD 파이프라인 보안 게이트 구축
사람이 일일이 패키지를 검사할 수 없으니 파이프라인이 스스로 거부권을 행사하게 만들어야 합니다. npm audit은 이미 알려진 CVE 데이터베이스만 봅니다. 제로데이 공격이나 알려지지 않은 악성 행동을 잡기에는 한계가 명확합니다.
- Socket.dev 통합: GitHub 저장소에 Socket CLI를 붙이십시오. 패키지가 네트워크에 접근하거나 셸 명령어를 실행하는 식의 위험 신호 70여 개를 실시간으로 분석합니다.
- Harden-Runner 적용: StepSecurity의 Harden-Runner를 GitHub Actions에 넣으세요. eBPF 기반으로 빌드 중에 발생하는 모든 아웃바운드 요청을 감시하고 승인되지 않은 도메인 접근을 차단합니다.
- 커스텀 린트 정책: ESLint의
no-restricted-imports규칙으로 Axios 같은 특정 라이브러리 사용을 막고 내부적으로 검증한 HTTP 클라이언트만 쓰도록 코드 수준에서 강제합니다.
Socket.dev 같은 행동 기반 분석을 도입하면 보안 사고 발생 시 수동 조사 시간을 매주 2시간 이상 아낄 수 있습니다.
| 도구명 | 분석 방식 | 도입 효과 |
|---|---|---|
| npm audit | CVE DB 대조 | 기본 내장 도구, 정적 취약점 분석 |
| Socket.dev | 행동 기반 분석 | 알려지지 않은 악성 코드 패턴 탐지 |
| Harden-Runner | eBPF 런타임 모니터링 | 빌드 서버의 수상한 네트워크 요청 차단 |
침해 사고 흔적 조사 및 복구
공격 소식을 들었다면 이미 늦었을지 모릅니다. 시스템 로그와 네트워크 활동 기록을 훑어 내 환경이 침해됐는지 확인하십시오. 악성 코드는 보통 C2 서버와 통신하려고 DNS 쿼리를 먼저 날립니다. 이 기록이 가장 확실한 단서입니다.
- DNS 쿼리 로그 분석:
tcpdump로sfrclak.com이나plaincryptojs관련 키워드가 포함된 요청이 있었는지 찾으세요. 발견하면 그 장비는 즉시 격리하십시오. - 비정상 프로세스 탐지:
ps -ef명령어로 부모 프로세스가npm인 자식 프로세스 중bun이나powershell이 떠 있는지 확인합니다. - 자격 증명 로테이션: 침해 가능성이 조금이라도 있다면 AWS 액세스 키, NPM 토큰, DB 암호를 다 바꾸십시오. 기존 세션도 전부 무효화해야 합니다.
공격자는 흔적을 지우려 하지만 node 외의 뜬금없는 프로세스를 만들거나 .github/workflows/ 밑에 이상한 YAML 파일을 심어 지속성을 확보하려 듭니다. Git status로 안 잡히는 신규 파일이 생겼는지 꼼꼼히 뒤져야 합니다. 네트워크 화이트리스트와 npm ci, 런타임 분석 도구라는 3단계 안전망을 구조화하면 보안 뉴스 하나에 온종일 가슴 졸이는 일은 확실히 줄어듭니다.
