러스트 악성 크레이트 arrayref 사태 총정리 — 2026년 빌드 타임 페이로드 공격 수법과 대응
러스트 생태계에서 특정 크레이트가 악성 코드를 실어 배포됐다는 이야기가 돌면, 개발자가 가장 먼저 확인해야 할 것은 “내 CI가 그 크레이트를 빌드한 적이 있는가”입니다. 러스트 공급망 공격의 핵심은 런타임이 아니라 빌드 타임에 있기 때문입니다. 이 글은 arrayref를 둘러싼 논란을 정리하되, 확인된 사실과 확인되지 않은 부분을 분리해서 다룹니다.
먼저, 확인된 것과 확인되지 않은 것
솔직하게 시작하겠습니다. 이 글을 쓰는 2026년 8월 21일 기준으로, 필자가 확보한 1차 자료에는 arrayref 크레이트가 악성 페이로드를 배포했다는 사실을 확정하는 공식 보안 공지가 포함되어 있지 않습니다. 따라서 피해 규모, 감염 버전 번호, 다운로드 수치 같은 구체적 숫자는 이 글에서 일절 언급하지 않습니다. 커뮤니티에서 도는 수치는 매체마다 다를 수 있으니 RustSec 권고와 crates.io 공식 공지를 직접 확인해야 합니다.
대신 확실한 것은 이겁니다. arrayref는 신생 크레이트가 아닙니다. 러스트 공식 포럼의 ‘Crate of the Week’ 스레드에서 2015년 9월 3일, 사용자 bluss가 owning_ref·newtype_derive와 함께 “Small” 크레이트 예시로 arrayref를 지목했을 만큼 오래된 유틸리티입니다. 즉 이름값이 있고, 의존성 트리 깊숙한 곳에 조용히 들어가 있을 가능성이 큰 부류라는 뜻입니다. 공격자가 노리는 표적의 전형입니다.
arrayref와 ArrayRef는 완전히 다릅니다
검색하다 보면 반드시 걸리는 함정입니다. 이름이 비슷할 뿐 전혀 다른 것들입니다.
| 이름 | 정체 | 정의 | 헷갈리면 생기는 일 |
|---|---|---|---|
arrayref |
독립 크레이트 | 배열 참조 유틸리티 매크로 | 엉뚱한 크레이트를 의존성에 추가 |
arrow::array::ArrayRef |
Apache Arrow 타입 별칭 | Arc<dyn Array> |
소유권 모델 오해 |
polars::prelude::ArrayRef |
Polars 타입 별칭 | Box<dyn Array> |
Arrow와 같은 타입으로 착각 |
Arrow는 Arc, Polars는 Box입니다. 같은 이름인데 참조 카운팅 여부가 다릅니다. 이 차이를 모르고 코드를 옮기면 컴파일 에러부터 성능 저하까지 줄줄이 따라옵니다. 그리고 보안 관점에서 더 중요한 건, 이런 이름 혼동이 타이포스쿼팅 공격의 최적 토양이라는 점입니다.
빌드 타임 페이로드 — 왜 런타임 방어가 무력한가
러스트 공급망 공격이 파이썬·npm과 결정적으로 다른 지점입니다. cargo build 한 번이면 다음 세 경로로 컴파일 중에 임의 코드가 실행됩니다.
1) build.rs
크레이트에 build.rs가 있으면 컴파일 전에 그 파일이 먼저 빌드되어 실행됩니다. 네트워크 요청, 파일 쓰기, 환경변수 읽기가 전부 가능합니다. CI 러너의 시크릿이 여기서 새어 나갑니다.
2) 프로시저럴 매크로
proc-macro 크레이트는 컴파일러 프로세스 안에서 코드로 실행됩니다. #[derive(...)] 하나가 실행 트리거가 됩니다.
3) 링크 단계 지시자
빌드 스크립트가 출력하는 링커 지시자를 통해 외부 오브젝트가 최종 바이너리에 섞여 들어갈 수 있습니다.
핵심은 이겁니다. 소스 코드를 아무리 읽어도 안전해 보이는데, 빌드하는 순간 이미 끝나 있는 구조입니다.
cargo build는 신뢰 경계를 넘는 행위입니다.
러스트 악성코드는 분석 자체가 어렵다
공격자가 러스트를 선호하는 이유는 분석 난도입니다. 데일리시큐가 2025년 6월 30일 보도한 마이크로소프트 위협 인텔리전스 센터(MSTIC) 자료에 따르면, 동일한 기능의 다운로더를 C++과 러스트로 각각 컴파일한 결과 C++ 실행파일은 20KB 미만·함수 100개 이하였지만 러스트 버전은 3MB 이상·함수 1만 개에 달했습니다. 대규모 정적 링크와 이름 맹글링 탓입니다.
※ 위 값은 MSTIC가 밝힌 “20KB 미만 / 100개 이하”, “3MB 이상 / 1만 개”의 경계 수치를 그대로 옮긴 것으로, 정확한 실측값이 아니라 비교 기준입니다.
같은 보도에 따르면 러스트 기반 악성코드는 2021년 블랙캣/ALPHV 랜섬웨어 등장 이후 늘었고, 2022년 하이브 랜섬웨어가 전면 러스트로 재작성, 2023년에는 러스트 정보탈취기가 깃허브 코드스페이스를 악용했으며, 2025년 3월 랜섬웨어 ‘RALord’, 5월 러스트 버전 어싱크랫(AsyncRAT)까지 이어졌습니다.
실무 대응 도구 — 무엇을 먼저 깔아야 하나
필자가 실제로 러스트 CI에 붙여 본 순서대로 정리했습니다. 다행히 이 영역의 핵심 도구는 대부분 무료 오픈소스라 가성비가 압도적입니다.
| 도구 | 역할 | 도입 포인트 | 추천 대상 |
|---|---|---|---|
cargo-audit |
RustSec 권고 DB 대조 | 5분이면 CI에 붙음, 무료 | 모든 러스트 프로젝트 (1순위) |
cargo-deny |
라이선스·중복·금지 크레이트 정책 | 정책을 파일로 고정 가능 | 사내 규정이 있는 팀 |
cargo-vet |
의존성 사람 검수 이력 공유 | 조직 간 검수 결과 재사용 | 의존성 수백 개 이상인 조직 |
--offline + 락파일 고정 |
빌드 재현성 확보 | 별도 설치 불필요 | 릴리스 빌드 파이프라인 |
| RIFT (MSTIC) | 러스트 악성 바이너리 분석 | 깃허브에서 무료 다운로드 | 침해사고 대응·분석 담당자 |
특히 사고가 이미 터진 뒤 바이너리를 뜯어야 하는 상황이라면, 이 작업에는 RIFT가 가장 적합했습니다. MSTIC 발표에 따르면 RIFT는 세 부분으로 구성됩니다. Static Analyzer가 바이너리에서 컴파일러 커밋 해시와 의존성 크레이트를 뽑아 JSON으로 저장하고, Generator가 같은 컴파일러·라이브러리를 재구성해 FLIRT 시그니처와 바이너리 디프를 만들며, Diff Applier 플러그인이 IDA Pro에서 라이브러리 함수에 일괄로 이름을 붙입니다. RALord 랜섬웨어에 적용했을 때 메인 함수 대부분의 라이브러리 코드가 자동 표시돼 분석가는 공격자 로직만 보면 됐다고 합니다.
다만 무비판적 신뢰는 금물입니다. 같은 보도에서 체크포인트 리서치는 맹글링 해제 후 함수 이름을 반드시 수동 검증하라고 조언했고, 디아포라 개발자 조세안 코렛은 머신러닝 기반 매칭이 “아직 실험 단계”라고 선을 그었습니다. 트렌드마이크로 연구진은 정적 도구만으로는 클라우드 API 악용 같은 동적 행위를 놓칠 수 있어 샌드박스 분석과 네트워크 모니터링을 병행해야 한다고 강조했습니다.
※ 위 인용처 중 MSTIC는 RIFT의 개발·배포 주체이자 보안 제품 공급사이고, 디아포라 개발자·체크포인트·트렌드마이크로는 경쟁·인접 분석 도구나 보안 솔루션을 제공하는 곳입니다. 이해관계를 감안해 읽으시길 권합니다. 이 단락의 수치·인용은 모두 데일리시큐(2025-06-30) 보도를 근거로 합니다.
오늘 당장 할 수 있는 것
– Cargo.lock을 저장소에 커밋하고, CI는 락파일을 고정한 채 빌드합니다.
– cargo tree로 문제 크레이트가 트리에 있는지부터 확인합니다. 직접 의존이 아니라 전이 의존으로 들어와 있는 경우가 대부분입니다.
– CI 러너에 장기 시크릿을 두지 않습니다. 빌드 타임 페이로드의 최우선 목표가 그것입니다.
– 의존성 추가 시 build.rs와 proc-macro 유무를 먼저 봅니다.
– 이름이 비슷한 크레이트는 철자를 두 번 확인합니다. arrayref와 ArrayRef 사례가 보여주듯, 혼동 가능한 이름 자체가 공격면입니다.
결론 — 가장 추천하는 조합
예방은 cargo-audit + 락파일 고정, 정책화가 필요하면 cargo-deny, 사고 대응은 RIFT. 이 셋이 현재 무료로 구할 수 있는 최선의 조합입니다. 비용이 0에 가까운데 막아 주는 범위는 CI 시크릿 전체이니, 도입을 미룰 이유가 없습니다.
그리고 arrayref 관련 개별 사안의 확정 사실관계는 RustSec 권고와 crates.io 공식 공지를 직접 확인하시기 바랍니다. 커뮤니티 요약본을 근거로 대응 범위를 판단하는 것이 가장 위험합니다.
참고 자료
– Crate of the Week – community – The Rust Programming Language Forum
– ArrayRef in arrow::array
– ArrayRef in polars::prelude – Rust
– 마이크로소프트, 최근 확산되는 러스트 악성코드 분석 도구 ‘RIFT’ 공개
자주 묻는 질문
arrayref 크레이트가 실제로 악성 코드를 배포한 게 확정된 사실인가요?
이 글이 확보한 1차 자료에는 그것을 확정하는 공식 보안 공지가 포함되어 있지 않습니다. 따라서 감염 버전이나 피해 규모 같은 구체적 수치는 단정할 수 없으며, RustSec 권고와 crates.io 공식 공지를 직접 확인해야 합니다. 다만 arrayref가 2015년 러스트 공식 포럼에서 소개될 만큼 오래된 유틸리티 크레이트라는 점은 확인됩니다.
빌드 타임 페이로드는 소스 코드 리뷰로 못 막나요?
build.rs와 프로시저럴 매크로는 컴파일 과정에서 실행되기 때문에, 라이브러리 본문 코드가 아무리 깨끗해도 cargo build 한 번으로 임의 코드가 돌아갑니다. 소스 리뷰만으로는 부족하고 CI 러너에서 시크릿을 분리하는 것이 핵심 방어입니다.
러스트 악성코드 분석은 왜 C++보다 어렵나요?
MSTIC가 동일 기능 다운로더를 두 언어로 컴파일해 비교한 결과, C++은 20KB 미만·함수 100개 이하였던 반면 러스트는 3MB 이상·함수 1만 개에 달했습니다(데일리시큐 2025년 6월 30일 보도). 대규모 정적 링크와 이름 맹글링 때문에 라이브러리 코드를 걷어내는 데만 시간이 크게 듭니다.