주요 내용
- 2025년 12월, 잭슨(Jackson)과 네임스페이스 구간 하나만 떨어진 곳에 게시된 한 패키지가 메이븐 센트럴(Maven Central)에서 코발트 스트라이크(Cobalt Strike)를 제공했으나, 관련 CVE는 없었습니다.
- Maven Central은 네임스페이스의 도메인 또는 호스팅 계정에 대한 관리 권한을 확인하며, 해당 네임스페이스가 닮은 프로젝트와의 연관성은 확인하지 않습니다.
- Maven Central을 통해 공개된 아티팩트에는 PGP 서명이 포함되어 있으나, Maven은 기본적으로 이를 검증하지 않습니다.
- 2025년 11월, 악성 코드가 삽입된 npm 패키지가 mvnpm 미러링 과정을 통해 Maven Central에 자동으로 유입되었습니다.
Log4Shell 사태 이후 자바 공급망과 관련해 제기된 논의의 대부분은 합법적인 코드 내에 존재하는 취약점이라는 한 가지 유형의 문제에 집중되어 왔습니다. 그러던 중 2025년 12월, 또 다른 문제가 드러났습니다. 네임스페이스 사칭 공격을 통해 잭슨(Jackson)의 실제 좌표 중 한 구간만 바꾼 좌표를 사용해 코발트 스트라이크(Cobalt Strike) 로더가 메이븐 센트럴(Maven Central)에 등록된 것입니다.
어떤 것도 악용된 바가 없습니다. 취약점도 전혀 관련되지 않았습니다. 누군가가 네임스페이스를 등록하고, 아티팩트를 공개한 뒤, 잘못된 좌표가 복사되기를 기다렸을 뿐입니다.
Maven Central의 보안 문제는 대부분의 사람들이 생각하는 것처럼 단순히 서명 검증의 허점만 있는 것이 아닙니다. 이는 네임스페이스 문제이기도 한데, 대부분의 Java 툴은 이 두 가지 문제 모두를 감지하지 못합니다.
잭슨의 가짜 택배 사건, 실제로 무슨 일이 있었을까
그 작동 원리는 한 문장으로 설명할 수 있을 만큼 간단하며, 바로 그 점이 성공의 비결이었다.
Jackson 2.x는 다음 라이선스에 따라 배포됩니다. com.fasterxml.jackson.core:jackson-databind. 12월 25일 해당 소포를 발견한 아이키도 시큐리티는, 악성 아티팩트를 기록하였다 ~처럼 org.fasterxml.jackson.core 같은 jackson-databind artifactId 때문에 전체 좌표 문자열이 3자나 어긋났습니다. 리버스 도메인 명명 방식은 이러한 문제를 방지하기 위한 것이며, 그 자체로 보면 약속한 바를 제대로 이행했습니다. Maven Central은 게시자가 네임스페이스와 일치하는 도메인을 소유하고 있음을 확인했습니다. 해당 도메인은 fasterxml.org로, 분석 8일 전인 2025년 12월 17일에 GoDaddy를 통해 등록되었으며, 실제 fasterxml.com과 거의 똑같은 도메인이었습니다. 소유권 확인은 올바르게 작동했습니다. 다만 잘못된 대상을 확인했을 뿐입니다.
이 페이로드는 단순히 훔쳐 달아나는 식의 즉흥적인 공격이 아니었다. 난독화를 제거해 보니, 해당 클래스는 가짜 Spring Boot 자동 구성이었으며, 이를 조사한 연구원들은 다단계 설계를 발견했다: 하드코딩된 키로 잠금이 해제된 AES 암호화 구성 문자열, 한 @Configuration 다음 주석이 달린 클래스 @ConditionalOnClass(ApplicationRunner.class) 따라서 Spring은 이를 등록하고 애플리케이션 컨텍스트가 로드되면 페이로드를 실행하게 되는데, 이는 IntelliJ 파일로 위장한 지속성 마커와, 명령 및 제어 트래픽이 외부로 전송되기 전에 수행되는 플랫폼 지문 인식 기능이었다. Windows 호스트는 다음을 다운로드했다. svchosts.exe, 실제 사이트의 타이포스쿼트인 svchost.exe 프로세스. 리눅스 및 macOS 호스트에서는 VirusTotal의 거의 모든 스캔 엔진이 ‘코발트 스트라이크(Cobalt Strike)’ 비콘으로 식별한 바이너리가 발견되었는데, 이는 유출된 빌드가 랜섬웨어 운영자 및 APT 그룹에 널리 사용되고 있는 상용 레드팀 프레임워크이다.
해당 패키지가 신고된 후, Maven Central은 약 90분 만에 이를 제거했는데, 이는 공개 레지스트리 치고는 매우 빠른 대응입니다. 하지만 이러한 속도는 해당 패키지가 활성화된 상태에서 이를 해결한 프로젝트들에게는 별 도움이 되지 않으며, 동일한 수법을 더 은밀하게 사용한 경우의 결과는 예측할 수 없습니다. 눈에 띄는 코발트 스트라이크(Cobalt Strike) 비콘은 발견되기 마련입니다. 하지만 잠복해 있으면서 서서히 정보를 유출하도록 설계된 것은 훨씬 더 오랫동안 시스템에 남아 있을 수 있습니다.
Maven Central에서 네임스페이스 사칭이 작동하는 방식
Maven은 groupId, artifactId, version이라는 세 가지 좌표로 종속성을 식별합니다.
일반적으로 groupId는 게시자가 관리하는 도메인의 역방향 도메인이며, Maven Central은 등록 시 해당 도메인 또는 이와 연결된 코드 호스팅 계정에 대한 관리 권한 증명을 요구함으로써 이를 준수하도록 합니다. 이러한 검증 절차는 실제로 이루어지며, 설계된 대로 정확히 작동합니다.
사람들이 생각하는 그런 역할을 하지는 않습니다. 도메인에 대한 관리권을 입증한다고 해서, 해당 도메인이 닮은 프로젝트와 게시자가 어떤 관계가 있는지 여부는 알 수 없습니다. 이는 단지 도메인에 대한 관리권을 확인해 줄 뿐이며, 닮은 도메인을 등록하는 데는 몇 달러밖에 들지 않습니다.
잭슨의 실제 네임스페이스와, 누구나 등록할 수 있는 세 가지 패턴이 나란히 있는데, 그중 어느 것도 여기에서 사용된 패턴은 아닙니다.
| 좌표 패턴 | 다음과 같은 이유로 타당해 보입니다. | 실제로 검증되는 내용은 무엇인가 |
|---|---|---|
com.fasterxml.jackson.core |
이것이 바로 실제 네임스페이스입니다 | FasterXML을 통한 도메인 제어 |
io.fasterxml.jackson |
역도메인인 .io는 오픈소스 소프트웨어(OSS)에서 흔히 사용됩니다. | 도메인을 구매한 사람이 도메인을 관리합니다 |
com.fasterxml-jackson.core |
하이픈이 하나만 있어도, 한눈에 봤을 때 똑같이 읽힙니다 | 도메인을 구매한 사람이 도메인을 관리합니다 |
org.jackson.databind |
프로젝트 이름과 일치합니다 | 도메인을 구매한 사람이 도메인을 관리합니다 |
그리고 io.fasterxml.jackson, com.fasterxml-jackson.core, 그리고 org.jackson.databind 모든 변형 도메인은 합법적인 경로를 통해 접근 가능하며, 어느 부분도 손상된 점이 없습니다. 잭슨 사건에서는 동일한 개념을 좀 더 제한적으로 적용했는데, 하이픈이나 다른 TLD를 사용한 것이 아니라 ‘com’을 ‘org’로 바꾼 단일 최상위 도메인 세그먼트를 사용했으며, 이 변경이 검증 과정을 통과할 수 있도록 특별히 등록된 도메인과 결합했습니다.
좌표는 기억을 더듬어 직접 입력하기보다는 스택 오버플로우 답변, 블로그 게시물, AI가 생성한 코드 조각 등에서 복사해 오는 경향이 있는데, 이것이 자바에서는 npm 패키지보다 오류를 발견하기가 더 어려운 이유 중 하나입니다. axios를 50번이나 설치해 본 개발자라면 “axois”라는 오류를 즉시 알아차릴 것입니다. Jackson의 groupId를 외우고 있는 사람은 거의 없으며, 읽기보다는 복사하여 붙여넣기만 하는 40자 길이의 문자열에서 한 부분이 뒤바뀐 것을 알아차리는 사람은 더욱 드물 것입니다.
프로젝트의 자체 문서 대신 검색 결과 페이지에서 좌표를 복사하는 것은 네임스페이스 혼동을 야기할 수 있는 또 다른 원인이 됩니다. 이번 특정 사건이 어떻게 전개되었든 간에, 그런 습관을 고치는 것이 좋습니다.
아무도 확인하지 않는 Maven Central의 보안 취약점
자바 개발자들 중 자세히 살펴보지 않은 사람들에게는 이 부분이 놀랍게 느껴질 텐데, 이는 앞서 언급한 문제와는 별개의 문제입니다.
Maven Central은 PGP 서명이 없는 릴리스를 허용하지 않습니다. Central을 통해 게시되는 모든 아티팩트에는 .asc 그 옆에 있는 파일과 체크섬까지 포함되며, 게시 요건은 npm이나 PyPI보다 더 엄격합니다. 이것이 바로 진정한 강점입니다.
Maven은 기본적으로 해당 서명을 검증하지 않습니다.
실행 mvn install 200개의 전이적 종속성이 있는 프로젝트에서 Maven이 200개의 JAR 파일을 가져와 해당 파일에 저장된 체크섬을 비교합니다. 기본적으로 체크섬이 일치하지 않을 경우 경고만 표시되며, 그중 하나만으로도 빌드가 실패하려면 -C, 또는 a checksumPolicy 저장소에서 실패했습니다. 어느 쪽이든, .asc 플러그인이 해당 JAR 파일들을 요청하지 않는 한, 그 옆에 있는 파일들은 절대 건드리지 않습니다.
체크섬 검증과 서명 검증은 종종 같은 것으로 취급되지만, 사실 둘은 다릅니다. 체크섬은 수신된 파일이 저장소에서 제공하는 파일과 일치하는지 확인합니다. 유효한 서명은 해당 아티팩트가 특정 개인 키로 서명되었음을 증명하며, 해당 키를 신뢰할 만한 게시자와 연결하기 위해서는 신뢰할 수 있는 키 매핑이 필요합니다. Maven은 기본적으로 첫 번째 검증만 수행하고, 두 번째 검증은 완전히 생략합니다.
이는 이 상황에서 무엇이 도움이 되었을지, 무엇이 도움이 되지 않았을지를 파악하는 데 중요한 요소입니다. 공격자는 fasterxml.org를 장악하고 있었으며 자신의 키로 서명할 수 있었기 때문에, 악성 패키지에 대해서도 서명 검증이 통과되었을 것입니다. 서명 검사는 해당 키 소유자가 서명한 이후로 아티팩트가 변경되지 않았음을 증명할 뿐입니다. 그 게시자가 네임스페이스가 암시하는 인물인지 여부에 대해서는 아무런 정보를 제공하지 않습니다. 두 가지 문제, 두 가지 해결책입니다.
이 부분에서는 Gradle이 Maven보다 앞서 있지만, 대부분의 팀은 아직 이를 활성화하지 않은 상태입니다.
./gradlew --write-verification-metadata sha256,pgp help
그것이 부트스트랩을 통해 verification-metadata.xml Gradle이 해결해 낸 파일이라면 무엇이든 상관없으며, 부트스트랩 단계가 속도를 늦출 만한 부분입니다. 이는 의도적으로 낙관적인 접근 방식입니다. 성공적으로 검증된 키는 자동으로 신뢰 목록에 추가되며, 사용 가능한 서명이 없는 아티팩트는 체크섬으로 대체되고, 트리 내에서 이미 손상된 항목은 처리 과정에서 승인됩니다. 파일을 커밋하기 전에 생성된 체크섬과 신뢰할 수 있는 키를 확인하십시오. 일단 기준선이 검토되면, Gradle은 더 이상 일치하지 않는 항목에 대해 빌드를 실패 처리합니다. 이는 강력한 통제 수단이며, 단순한 프로젝트에서는 큰 부담이 되지 않습니다.
Maven에는 코어에 이에 상응하는 기능이 없습니다. 검증은 플러그인을 의미합니다.
mvn org.simplify4u.plugins:pgpverify-maven-plugin:1.19.1:check
이 기능은 종속성 서명을 검증하며 명시적인 키 맵을 지정할 수 있으므로, 사용자가 지정한 서명 키만 신뢰할 수 있는 키로 간주됩니다. 이 기능은 제대로 작동하며, 기본적으로 설정되어 있는 방식과는 다릅니다.
이 두 가지 제어 방식의 근저에는 ‘아티팩트 대 소스’ 문제가 자리 잡고 있습니다. JAR 파일은 빌드 산출물일 뿐이며, 프로젝트가 연결된 소스 리포지토리와 반드시 일치해야 할 의무는 없기 때문입니다. 공개된 바이너리를 읽는 스캐너는 서명이 되어 있든 없든, 게시자가 그곳에 포함시키기로 선택한 내용만을 확인합니다. 검증된 소스를 바탕으로 다시 빌드해야만 게시자의 바이너리를 신뢰하는 대신 아티팩트에 무엇이 포함되었는지에 대한 독립적인 확인을 얻을 수 있으며, SecureChain for Java는 바로 이러한 전제를 바탕으로 구축되었습니다.
MavenGate와 버려진 코디네이트의 문제점
2024년 1월 Oversecured의 연구원들이 발표한 ‘MavenGate’는 유사한 결과를 초래하는 또 다른 경로를 설명했는데, 이 방법은 신원 사칭이 전혀 필요하지 않기 때문에 오히려 더 우려스러운 것으로 볼 수 있다.
이 기법은 더 이상 유지보수되지 않는 종속성을 대상으로 합니다. 수년 전에 다음 조건 하에 공개된 라이브러리는 com.oldcompany.util 수천 개의 종속성 트리에 포함되어 있습니다. 회사가 문을 닫고 도메인이 만료되어도, 해당 아티팩트는 여전히 Maven Central에서 완벽하게 해결되므로 아무도 눈치채지 못합니다.
그 다음에 일어나는 일은 말처럼 자동으로 진행되지는 않습니다. 특정 저장소에서 해당 groupId를 관리하는 계정이 없는 경우, 현재 해당 도메인을 소유한 사람은 DNS TXT 레코드를 통해 이를 청구할 수 있습니다. groupId가 이미 등록된 경우, 이를 인수하려면 해당 저장소의 지원팀을 설득하여 접근 권한을 이전받아야 하는데, Oversecured는 이러한 이전 절차가 어떻게 진행되는지에 대한 정보가 전혀 없다고 분명히 밝혔습니다. 위험의 상당 부분은 여러 저장소를 아우르는 프로젝트에서 비롯되는데, 목록의 다른 곳에 악성 버전이 도입되더라도 빌드가 이미 신뢰하는 좌표 하에 해당 버전이 전달되기 때문입니다. 버전 범위를 사용하거나 공격자의 버전으로 업그레이드하는 프로젝트는 낯선 이름을 전혀 확인하지 못한 채 해당 버전을 받아들여 버립니다.
규모는 작동 원리보다 파악하기가 더 쉽습니다. Oversecured는 Maven Central의 groupId를 도메인으로 변환한 뒤, 그중 단순히 구매할 수 있는 도메인이 있는지 확인한 결과, 26,163개 도메인 중 3,710개(14.18%)가 구매 가능한 것으로 나타났습니다. 이를 GitHub 기반 네임스페이스와 연구진이 찾아낸 비공개 저장소까지 확대해 보면, 33,938개의 식별자로 구성된 데이터셋 중 18.18%가 노출된 것으로 나타났습니다.
Sonatype은 이미 구축된 자동화 시스템을 고려할 때 해당 공격의 실현 가능성에 대해 반박한 뒤, 만료된 도메인과 연결된 계정을 비활성화하고, 네임스페이스 검증 절차를 강화했으며, 어디에도 공개된 적이 없는 키로 서명된 아티팩트가 통과되도록 했던 공개 키 검증 회귀 문제를 수정했습니다. Oversecured의 답변에 따르면, 이 공격은 여러 공개 저장소에서 동시에 프로젝트를 조회할 때 발생하기 때문에 단일 레지스트리만으로는 이 문제를 해결할 수 없으며, 저장소 소유자가 할 수 있는 최선의 조치는 이미 취약점으로 표시된 네임스페이스에 대한 자동 클레임을 거부하는 것뿐이라고 했다.
Maven Central의 일반적인 정책에 따르면, 공개된 릴리스는 변경할 수 없으므로 게시자가 버전을 몰래 수정하거나 철회할 수 없으며, 잭슨(Jackson) 사례와 같은 보안상의 이유로 인한 삭제는 극히 드문 예외에 해당합니다. 이는 재현성을 확보하는 데 유용합니다. 또한 이는 네임스페이스 뒤에 있는 도메인이나 계정이 더 이상 유지 관리되지 않는 지 오래되었음에도 불구하고, 버려진 의존성은 여전히 해결 가능하며 의존성 트리의 깊은 곳에 남아, 내부에서는 정상적인 의존성과 똑같이 보인다는 것을 의미합니다. pom.xml.
CVE가 등록되면 해당 라이브러리들은 어떻게 되는지, 이에 대한 명확한 답은 없습니다. 패치된 버전으로 업그레이드할 수 있는 방법이 없으며, 보안과 관련된 자바 라이브러리를 자체 저장소에 벤더링하면, 이를 담당할 인력이 있든 없든 상관없이 해당 팀의 책임 하에 CVE가 관리되게 됩니다.
보안 취약점이 있는 npm 패키지가 Maven Central에 어떻게 유입되었는가
대부분의 자바 팀이 간과하는 점은, 팀원 중 누구도 npm을 직접 다룰 필요 없이도 이런 일이 발생할 수 있다는 사실입니다.
2025년 11월, 제2차 Shai-Hulud npm 웜이 Maven Central에 등장했다 자동화된 mvnpm 미러링을 통해 이루어집니다. mvnpm은 npm 패키지를 Maven 아티팩트로 재게시하므로, 자바 웹 프로젝트는 별도의 자바스크립트 툴체인을 사용하지 않고도 일반적인 빌드 과정을 통해 프론트엔드 라이브러리를 가져올 수 있습니다. 이 미러링은 자동화되어 있으며, 새로운 npm 릴리스는 게시되는 즉시 동기화됩니다. 이것이 바로 이 도구의 핵심 목적이자, 해킹당한 패키지가 유포된 정확한 경로이기도 합니다. npm의 악성 릴리스는 posthog-node 패키지가 Maven Central에 다음과 같이 재빌드되었습니다. org.mvnpm:posthog-node:4.18.1, 동일한 것을 담고 있는 setup_bun.js 로더 및 bun_environment.js 페이로드를 npm 측의 ‘Shai-Hulud’ 캠페인.
Socket이 이 아티팩트를 신고했고, Maven Central은 침해된 릴리스가 자동화된 mvnpm 프로세스를 통해 배포된 것임을 확인한 후, 당일 모든 미러 사본을 삭제했습니다. PostHog은 Maven에 아티팩트를 전혀 게시하지 않습니다. 이 웜이 Maven 생태계 내에서 자가 전파되는 행태를 보인 증거는 없으며, 미러링된 아티팩트 한 건만이 확인되었습니다. 이러한 차이는 이번 사건을 일회성 사건이 아닌 실제 Maven 공급망 패턴으로 얼마나 심각하게 받아들여야 하는지에 있어 중요한 요소입니다. 이 사건은 실제로 발생했고 자동으로 진행되었으며, 손상된 npm 릴리스가 Java 빌드에 사용 가능하게 되기 위해 Java 유지보수 담당자가 별도로 재게시할 필요가 없었지만, 일단 그곳에 도달한 후에는 웜처럼 행동하지는 않았습니다.
이것이 보여주는 것은, 자동 미러링이 누구도 의도하지 않았음에도 신뢰 경계를 이동시킨다는 사실입니다. npm을 한 번도 다뤄본 적 없는 자바 개발 팀조차도, 브리지 서비스가 대신 해당 npm 패키지를 JAR 파일로 변환했기 때문에 결국 보안이 침해된 npm 패키지를 불러오게 될 수 있습니다.
| Java 빌드 경로 | 팀이 npm을 사용해야 합니다. | pom.xml에서 확인할 수 있음 |
|---|---|---|
| JS 툴체인을 통한 npm 직접 종속성 | 예 | 아니요 |
| 브리지 서비스에서 미러링된 npm 아티팩트 | 아니요 | 네, 일반적인 JAR 파일처럼요 |
| 미러된 아티팩트를 가져오는 전이적 Java 종속성 | 아니요 | 다음과 같은 경우에만 dependency:tree |
그곳에 무엇이 있어야 할지 추론하기보다는 전이 경로를 직접 확인해 보세요. 트리에 실제로 무엇이 있는지 파악하세요.
mvn dependency:tree -DoutputFile=deps.txt
그렇다면 내용을 읽어보세요. 중간 규모의 Spring 서비스는 선언된 수십 개의 의존성에서 수백 개의 아티팩트를 쉽게 해결해 낼 수 있습니다. 미러링된 패키지는 해당 출력에서 org.mvnpm 좌표. 팀원 중 누군가 ‘네임스페이스’가 Maven용으로 재포장된 npm 코드를 의미한다는 사실을 알고 있다면, 이는 확실한 단서가 됩니다.
이번 달 빌드에서 변경해야 할 사항
두 방법의 작업량이 동일하지 않으므로, 현재 사용 중인 빌드 도구를 먼저 사용해 보세요. Gradle은 다음을 통해 의존성 검증을 신속하게 시작할 수 있습니다. --write-verification-metadata sha256,pgp, 그러면 파일이 커밋되기 전에 생성된 해시와 키를 검토하기만 하면 됩니다. Maven에는 이에 상응하는 기본 기능이 없으므로, 플러그인을 추가하고 버전을 고정해야 합니다. pluginManagement, 준비 과정은 더 많이 필요하지만 여전히 일주일 분량의 작업일 뿐, 분기 단위의 작업은 아닙니다.
그렇다면 실제로 잭슨 패키지가 통과하게 만든 그 관행을 살펴보겠습니다. 좌표 정보는 프로젝트 자체 문서와 대조해 확인하기보다는 발견되는 대로 복사되어 사용되는데, 이는 도구보다 규칙을 통해 수정하는 편이 더 쉽습니다. 팀이 이전에 사용한 적이 없는 groupId는 프로젝트의 공식 저장소나 문서에 있는 좌표 정보와 대조하여 확인한 후, 해당 groupId가 pom.xml, 특히 검색 결과나 AI가 생성한 발췌문에서 가져온 내용은 더욱 그렇습니다.
버려진 종속성의 경우 다른 종류의 판단이 필요하며, 그 이유는 바로 ‘MavenGate’ 사건 때문입니다. 최근 릴리스가 없고 활동 중인 유지보수자가 없는 아티팩트는 현재 공개된 CVE가 있든 없든 인수 대상이 됩니다. 왜냐하면 위험은 코드에 있는 것이 아니라, 해당 네임스페이스 뒤에 있는 도메인이나 계정을 여전히 관리하는 사람이 있는지 여부에 있기 때문입니다.
지난 몇 년 사이에 시작된 Gradle 프로젝트라면 하루 만에 검증 기능을 도입할 수 있습니다. 반면, 사용자 정의 부모 POM과 40개의 플러그인을 사용하는 10년 된 다중 모듈 Maven 빌드의 경우 이야기가 달라지며, 두 경우 간의 구현 난이도는 실제로 그만큼 차이가 납니다.
SecureChain의 적용 분야
Maven Central은 데이터가 유입될 때 네임스페이스 소유권을 확인하며, Maven은 데이터가 배포될 때 리포지토리 체크섬을 비교합니다. 기본 경로에서는 해결된 바이너리가 프로젝트에서 실제로 빌드된 것과 일치하는지 확인할 수 있는 방법이 없습니다. SecureChain for Java는 이러한 해결 경로를 대체하여, 검증된 소스 코드로부터 모든 패키지를 재빌드하고, 빌드에 도달하기 전에 악의적인 행동을 걸러내며, 업스트림 지원이 종료된 후에도 지속적으로 패치를 적용합니다. 기존 Maven 또는 Gradle 워크플로는 그대로 유지됩니다. TuxCare를 지정하기만 하면 계속 빌드할 수 있습니다.
SecureChain for OSS가 어떤 내용을 다루는지 확인해 보시거나, 뉴스레터를 구독하여 이와 같은 사고 분석 정보를 발생 즉시 받아보세요.
자주 묻는 질문
Maven Central에서 네임스페이스 사칭이란 무엇인가요?
합법적인 프로젝트의 네임스페이스와 유사하게 구성된 groupId로 아티팩트를 게시하는 행위. Maven Central은 게시자가 해당 도메인이나 호스팅 계정을 관리하고 있는지 확인하며, 이를 통해 해당 네임스페이스에 대한 관리 권한을 검증할 뿐, 모방 대상 프로젝트와의 관계에 대해서는 아무런 판단을 내리지 않습니다.
Maven은 PGP 서명을 검증하나요?
기본적으로는 아닙니다. Maven Central은 게시된 아티팩트에 PGP 서명을 요구하며, Maven은 저장소의 체크섬을 비교하지만 기본적으로 해당 서명이나 신뢰할 수 있는 키 매핑을 검증하지는 않습니다. 검증을 하려면 pgpverify-maven-plugin과 같은 플러그인이 필요합니다.
Gradle에서 종속성 검증을 활성화하려면 어떻게 해야 하나요?
실행 ./gradlew --write-verification-metadata sha256,pgp help ~을 부트스트랩하기 위해 verification-metadata.xml 파일을 확인하고, 생성된 체크섬과 신뢰할 수 있는 키를 검토한 다음 해당 기준선을 커밋합니다. 그 후, Gradle은 체크섬이나 서명이 더 이상 일치하지 않는 아티팩트가 있으면 빌드를 실패로 처리합니다.
MavenGate란 무엇인가요?
2024년 1월 Oversecured 연구진이 발표한, 방치된 종속성을 노리는 해킹 기법입니다. 오래된 groupId에 연결된 만료된 도메인이나 계정을 확보한 사람은, 해당 네임스페이스를 관리하는 주체가 없는 저장소에서 그 네임스페이스를 차지하거나 기존 등록 정보에 대한 접근 권한을 얻으려 시도할 수 있으며, 여러 저장소를 가로질러 해결되는 프로젝트들은 익숙한 좌표 하에서 악성 아티팩트를 수용하게 될 수 있습니다.
보안 취약점이 있는 npm 패키지가 Java 프로젝트에 영향을 미칠 수 있나요?
네. npm 패키지를 Maven 아티팩트로 자동 재게시하는 브릿지 서비스는, 보안에 문제가 있는 npm 릴리스를 Maven Central로 유입시킬 수 있으며, 이 릴리스는 Maven Central에서 일반적인 JAR 파일로 변환되어 org.mvnpm 좌표. 이 좌표들은 브리지의 이름을 지정하지만, 네임스페이스를 인식하지 못하는 팀은 해당 아티팩트를 다른 의존성과 다를 바 없이 취급할 것입니다. 2025년 11월, Shai-Hulud 2.0이 mvnpm을 통해 Maven Central에 등록되었을 때 바로 그런 일이 발생했습니다.
내 Java 빌드에서 악성 Java 라이브러리가 포함된지 어떻게 알 수 있나요?
실행 mvn dependency:tree 또는 ./gradlew dependencies 그리고 익숙하지 않은 groupId는 검색 결과가 아닌 상위 프로젝트의 자체 문서를 참고하여 하나하나 확인해야 합니다. 개발이 중단된 프로젝트의 경우, 인수 위험을 CVE 상태와 별개로 다루어야 합니다. Maven Central의 네임스페이스 검증은 이름이 유사한 프로젝트와의 연관성이 아니라 도메인이나 호스팅 계정에 대한 관리 권한을 확인하는 데 그치기 때문에, 결국은 이러한 수동 검토가 필수적입니다. 또한 Maven은 기본적으로 의존성 서명을 인증하지 않습니다.
자바에는 npm의 postinstall 스크립트와 유사한 기능이 있나요?
의존성 설치용은 아니지만, Java 빌드에서는 여전히 신뢰할 수 없는 코드가 실행됩니다. Maven 플러그인은 빌드 라이프사이클 내에서 실행되고, 어노테이션 프로세서는 컴파일러 내부에서 실행되며, Gradle 빌드 스크립트는 단순한 구성이 아닌 실행 가능한 프로그램입니다. 가짜 Jackson 패키지는 런타임에 이와 유사한 기법을 사용하여 Spring이 해당 구성 클래스를 찾아내도록 하고, 이를 통해 페이로드를 대신 실행하게 했습니다.



