악성 패키지
악성 패키지는 소프트웨어 공급망 공격을 수행하는 인기 있고 성장하는 방법입니다. 이 페이지에서는 악성 패키지가 무엇인지, Snyk이 이를 어떻게 식별하는지, 그리고 프로젝트에 악성 패키지가 있는 경우 고객이 무엇을 해야 하는지 설명합니다.
Snyk은 스캔된 패키지의 출처나 기원을 고려하지 않습니다. 일부 경우, 스캔된 패키지의 에코시스템, 이름 및 버전이 악성 공개 패키지와 일치할 때 Snyk이 오탐(false positive)을 감지할 수 있습니다. 패키지의 출처를 반드시 확인하십시오.
악성 패키지 소개
오픈소스 악성 패키지
오픈소스 악성 패키지에는 공격을 수행하기 위해 의도적으로 삽입된 악성 코드가 포함되어 있습니다. 여기에는 대상 네트워크 감염, 비밀번호 및 신용카드 정보와 같은 민감한 정보 탈취 및 유출, 다운로드된 멀웨어 구성 요소에 의한 추가적인 악성 활동 수행 등이 포함됩니다.
악성 패키지는 npm, PyPI, NuGet, RubyGems 등을 포함한 인기 있는 패키지 레지스트리에 합법적인 패키지로 게시됩니다.
악성 패키지 큐레이션 프로세스
Snyk 보안 연구 팀은 매일 여러 소스를 모니터링하여 악성 패키지를 포함한 취약점을 식별, 분류 및 검증합니다. 여기에는 블로그, 소셜 미디어, 공식 패키지 레지스트리 공지사항의 인사이트와 내부 연구 도구를 사용한 사내 조사가 포함됩니다.
Snyk은 새로운 탐지 기술과 데이터 소스를 통합하여 접근 방식을 지속적으로 개선하며, 소프트웨어 에코시스템에서 새롭게 발생하는 위협에 대한 포괄적인 이해를 보장합니다. Snyk이 수행한 악성 패키지 연구의 몇 가지 예시는 다음과 같습니다.
악성 패키지에 대한 CVE ID 부재
일반적으로 오픈소스 취약점에는 CVE-2021-44228과 같은 CVE ID가 할당됩니다. CVE ID는 Snyk과 같은 보안 벤더가 공개적으로 공개된 취약점을 식별, 정의 및 카탈로그화하는 데 도움을 줍니다. 거의 모든 경우에 악성 패키지에는 CVE ID가 할당되지 않습니다. 이러한 식별자의 부재는 보안 커뮤니티에서 새로운 위협을 공유하는 것을 어렵게 만듭니다. Snyk은 패키지 이름, 패키지 레지스트리(예: npm), 그리고 영향을 받는 버전 범위를 사용하여 악성 패키지를 공개적으로 카탈로그화하고 공유합니다.
악성 패키지 - CWE-506
Snyk 취약점 데이터베이스에 있는 모든 악성 패키지에는 CWE-506 - Embedded Malicious Code 레이블이 지정되어 있습니다.
CWE-506으로 필터링함으로써 고객은 자신의 프로젝트 중에 악성 패키지가 있는지 신속하게 확인할 수 있습니다.
악성 패키지 심각도 - 치명적(Critical)
악성 패키지는 공격자가 대상 머신에서 원격 코드를 실행할 수 있게 할 수 있습니다. 본질적으로 이러한 패키지는 신뢰할 수 없으며 발견 후 언제든지 악성 기능을 추가하도록 업데이트될 수 있습니다. 따라서 Snyk은 악성 코드를 평가하고 거의 모든 경우에 치명적(Critical) 심각도 레벨을 할당합니다.
악성 패키지에 대한 해결 조언은 이를 설치하지 않거나 이미 설치된 경우 제거하는 것입니다.
악성 패키지 게시 타임라인
악성 패키지는 식별되어 제거될 때까지 몇 분 동안만 공개적으로 사용 가능할 수 있습니다. 다른 경우에는 악성 패키지가 타겟팅된 공급망 감염 캠페인에 포함되어 몇 달 또는 몇 년 동안 눈에 띄지 않을 수도 있습니다.
연구 및 방어 능력이 향상되는 동안, 공격자들은 발견을 피하기 위해 새로운 기술과 기술을 사용합니다. 사용자는 악성 패키지가 오랫동안 유포되었음에도 불구하고 Snyk 권고문이 최근에 게시된 것을 발견할 수 있습니다.
악성 패키지의 유형
악성 패키지의 유형은 매우 다양하며 정교한 해커들은 항상 새로운 유형을 발명해냅니다. 최근의 공급망 캠페인을 살펴보면 다음과 같은 일반적인 공격 벡터 클러스터를 관찰할 수 있습니다.
타이포스쿼팅 공격
악의적인 행위자가 사용자가 실수로 설치하기를 바라며 레지스트리에 합법적인 패키지와 유사한 이름의 악성 패키지를 게시합니다. 타이포스쿼팅 공격의 예로는 crossenv가 있습니다. 공격자는 인기 있는 패키지인 cross-env와 유사한 이름을 사용했으며, 모듈이 실제로 예상대로 작동한다는 것을 전달하기 위해 원래 모듈과 정확히 동일한 기능을 래핑하기도 했습니다. 그러나 이 모듈은 환경 변수를 캡처하여 공격자가 제어하는 원격 서버로 전송했습니다.
종속성 혼동 공격
종속성 혼동 공격은 공격자가 프라이빗 패키지 이름을 가진 악성 패키지를 공개 패키지 레지스트리에 업로드하는 전술입니다. 이로 인해 IDE 및 CI와 같이 패키지를 가져오는 자동화된 프로세스가 혼동을 일으켜 의도한 프라이빗 패키지 대신 공개 패키지를 다운로드하게 됩니다.
예를 들어, ACME 사는 acme-ui라는 이름의 내부 UI 패키지를 개발하여 프라이빗 패키지 레지스트리에 호스팅했습니다.
악의적인 사용자가 동일한 이름의 악성 패키지를 npm에 게시했습니다. ACME의 개발자가 프라이빗 레지스트리에서 패키지를 가져오도록 환경을 구성하지 않았습니다. 패키지를 설치하는 동안 개발자는 실수로 프라이빗 패키지 대신 공개 레지스트리에서 acme-ui 패키지를 다운로드했고, 악의적인 사용자가 개발자의 머신에서 코드를 실행할 수 있게 된 종속성 혼동의 성공 사례입니다.
종속성 하이재킹
이 공격에서 개발자가 사용하는 패키지는 합법적인 공개 패키지이지만, 해당 패키지가 하위 단계에서(예: 종속성 혼동으로 인해) 악성 패키지를 종속성으로 사용하고 있습니다.
이러한 유형의 공격에 대한 자세한 내용은 npm 패키지 event-stream에서 발견된 악성 코드 기사에 설명되어 있습니다.
계정 탈취
악의적인 행위자가 공개 패키지 유지관리자의 계정을 탈취하여 패키지에 악성 코드를 삽입할 수 있습니다.
이러한 유형의 공격에 대한 자세한 내용은 ESLint 패키지의 악성 버전 기사에 설명되어 있습니다.
패키지 출처 검증
현재 Snyk Open Source 및 Snyk Container 스캐너는 내부 패키지와 외부 패키지를 구분할 수 없습니다. 즉, 패키지가 공개 레지스트리에서 가져온 것인지 프라이빗 레지스트리에서 가져온 것인지 판단할 수 없습니다. 이 기능은 향후 추가될 예정입니다. 그동안 프라이빗 레지스트리에서 가져온 패키지와 관련된 부정확한 경고가 표시될 수 있습니다.
Snyk 경고는 공격이 조직을 타겟팅했다는 경고이지, 조직이 멀웨어를 게시했다는 의미가 아닙니다.
여러 에코시스템에서 증명(attestations) 검증 지원을 구현하기 시작했습니다. 예를 들어 공개 npm 레지스트리는 패키지 출처(provenance)에 대한 지원을 제공합니다. 유지관리자가 이 기능을 더 많이 채택하고 출처 세부 정보와 함께 패키지를 게시할수록, 패키지 출처를 검증하는 방법이 더 안전해지고 좋아집니다. Snyk은 오픈소스 패키지 소비 전략에서 이에 대한 대비를 시작할 것을 강력히 권장합니다.
내부 패키지가 악성으로 플래그 지정될 수 있습니다. 이런 일이 발생한다면, 공개 레지스트리에 유사한 이름의 패키지가 게시되었으며 악성 코드가 포함되었을 가능성이 매우 높다는 의미입니다. 이 게시물은 귀하의 회사 개발자가 합법적인 프라이빗 패키지 대신 자동 또는 수동 프로세스를 통해 악성 공개 패키지를 가져오도록 유도하기 위한 것입니다.
항상 npm 레지스트리 소스를 검증하여 악성 패키지를 피하십시오.
npm의 악성 패키지 이해
JavaScript와 npm의 인기 때문에 대부분의 악성 패키지는 이 에코시스템을 타겟팅합니다.
다음과 같은 뉘앙스를 이해하는 것이 중요합니다.
npm의 "보안 홀딩 (Security holding)"
패키지에 대한 "보안 홀딩"은 해당 패키지에 악성 코드가 포함되어 있어 npm 보안 팀에 의해 레지스트리에서 제거되었음을 의미합니다. 향후 사용자들이 영향을 받지 않도록 보안 플레이스홀더(security placeholder)가 게시되었습니다. 패키지가 현재 "보안 홀딩" 플레이스홀더 아래에 있더라도, 해당 패키지가 이 플레이스홀더로 표시되기 전에 npm에서 가져오지 않았는지 확인하는 것이 중요합니다. 이 패키지의 모든 인스턴스가 프라이빗 레지스트리에서 다운로드되었음을 확인한 후에는 이슈를 무시할 수 있습니다.
Snyk 취약점 데이터베이스도 flatmap-stream 패키지와 같이 "보안 홀딩" 상태인 패키지를 표시합니다.
npm에서 사용할 수 없고 "보안 홀딩"도 없는 악성 패키지
패키지가 소유자에 의해 제거(게시 취소)되기 전까지 잠시 동안 npm에 공개적으로 제공되었을 수 있습니다. 특정 조건 하에서 이는 패키지 페이지를 사용할 수 없게 만들 수 있지만, 한때 사용 중이었음을 확인할 수는 있습니다. 이름은 여전히 다시 사용될 수 있으며, 새로운 형태로 다시 나타났을 때 그 내용이 안전할 것이라는 보장은 없습니다.
이러한 경우 패키지가 어디에서 다운로드되었는지 각별히 주의해야 합니다. 이슈를 완전히 무시하면 나중에 악의적인 행위자가 해당 패키지를 npm에 다시 게시할 경우 문제가 발생할 수 있습니다.
npm 레지스트리 소스 검증
공개 레지스트리를 사용 중인지 프라이빗 레지스트리를 사용 중인지 확인하려면 다음 옵션을 사용할 수 있습니다.
CLI 명령 실행
다음 명령을 실행하십시오: npm config get registry
결과가 registry.npmjs.org라면 공개 레지스트리를 사용 중인 것입니다.
package-lock.json 파일 확인
package-lock.json 파일에는 프로젝트의 패키지 및 해당 소스에 대한 상세 정보가 포함되어 있습니다. 이 파일을 열고 각 종속성의 resolved 필드를 조사하여 각 종속성의 출처를 확인할 수 있습니다. 공개 npm 레지스트리의 패키지는 https://registry.npmjs.org/로 시작하는 URL을 가집니다.
.npmrc 파일 확인
프로젝트 루트 디렉토리의 .npmrc 파일은 npm이 패키지를 가져올 레지스트리를 지정할 수 있습니다. .npmrc 파일이 프라이빗 npm 레지스트리를 사용하도록 구성되어 있는지 확인하십시오.
프라이빗 레지스트리를 사용하는 경우 파일 경로는 다음과 같아야 합니다.
registry=https://your-private-registry-url/
.npmrc 파일이 없거나 레지스트리를 지정하지 않은 경우, npm은 기본 공개 레지스트리인 https://registry.npmjs.org/를 사용합니다.
npm과 함께 프라이빗 패키지 사용
npm을 사용하는 경우 npm 레지스트리에 프라이빗 패키지를 호스팅할 수 있습니다.
회사가 이 서비스를 사용 중인 경우 공개 레지스트리는 https://registry.npmjs.org가 됩니다.
이 경우 npm 웹사이트에 로그인하여 사용된 패키지가 프라이빗인지 확인해야 합니다.
악성 패키지 발견 시 해결 방법
환경에 악성 패키지가 설치되었다는 증거를 발견하면 다음을 수행해야 합니다.
로컬 드라이브의 로컬
node_modules폴더와 전역 패키지 관리자 캐시 모두에서 즉시 제거하십시오.패키지 레지스트리 프록시 캐시 및 데이터베이스가 있는 경우 거기서도 제거하십시오.
패키지 잠금 파일(npm의 경우
package-lock.json, Yarn의 경우yarn.lock)에서 제거하십시오.
다음 전술을 구현하여 악성 패키지의 특정 사례를 해결할 수 있습니다.
타이포스쿼팅: 악성 패키지를 제거하고 올바른 안전한 패키지로 전환하십시오.
종속성 혼동: 실수로 또는 CI의 기본 설정으로 인해 "보안 홀딩" 상태가 되기 전에 공개 패키지를 가져온 경우 반드시 제거하십시오. 개발 환경과 CI 파이프라인이 프라이빗 레지스트리를 사용하고 대신 동일한 이름의 내부 패키지를 설치하도록 구성되어 있는지 확인하십시오.
종속성 하이재킹 및 계정 탈취: 악성 패키지가 식별된 후에는 일반적으로 새로운 안전한 버전이 릴리스됩니다. 이러한 유형의 공격을 해결하려면 패키지를 새 버전으로 업데이트하십시오.
사용자의 환경이 감염되었다고 가정하고 내부 보안 점검을 실시하는 것이 중요합니다. 악성 패키지를 제거한 후 악성 코드의 잔재가 있는지 반드시 확인하십시오.
Last updated