월요일에 공개된 한 CVE는 Flair의 0.15.0 및 0.15.1 공식 wheel에 여전히 flair/models/clustering.py가 포함돼 있으며, 이 파일의 모델 로딩 경로가 pickle.loads(joblib.load(...))를 반환한다고 적시한다. 이는 2024년의 한 CVE와 같은 파일, 같은 sink에 관한 내용으로, 해당 CVE는 0.15.0을 수정 버전으로 제시했다.
‘수정됨’이 의미했던 것
클러스터링 지원은 0.15.0에서 — 문서화된 API에서 — 삭제됐다. 그러나 배포된 산출물에서는 제거되지 않았다. 이 모듈은 여전히 wheel에 들어 있으며 flair.models.clustering를 직접 import하면 접근할 수 있다. 새 권고문은 이를 분명히 밝힌다. “이전 기록의 수정 버전은 배포된 패키지에는 해당하지 않는다.”
통상적인 해석이 놓치는 점
여기서 함정은 코드가 아니라 메타데이터에 있다. CVE 기록의 “0.15.0에서 수정”은 코드가 패키지 밖으로 나갔다는 뜻으로 받아들여졌지만, 실제로는 유지관리자들이 해당 기능 지원을 중단했다는 의미였다. 소프트웨어 구성 분석 스캐너가 2024년 기록의 수정 버전 필드를 읽는다면 0.15.1 설치본을 정상으로 표시할 것이다. 그러나 실제로는 정상 상태가 아니다. 또 다른 오독은 반대로 경보를 부추긴다. 점수는 8.4와 7.8로 HIGH이지만 벡터는 로컬이다 — AV:L이며 사용자 상호작용이 필요하다. 피해자는 공격자가 제공한 모델 파일을 불러와야 한다. 이는 신뢰할 수 없는 가중치의 공급망 문제이지 네트워크 RCE가 아니며, 벡터 설명 없이 8.4만 언급하면 심각하게 과장하는 셈이다. 두 점수 모두 Secondary이며, NVD는 아직 primary CVSS를 발표하지 않았다.
상황을 더 악화시키는 날짜들
Flair 0.15.0은 2024년 12월 20일 PyPI에 업로드됐다. 0.15.1은 그 뒤를 이어 2025년 2월 5일에 배포됐고, 그 이후로 지금까지 현재 릴리스로 남아 있다. 약 18개월 동안 해당 파일은 존재했고, 기능은 문서에서 빠졌으며, 생태계의 메타데이터는 문제가 해결됐다고 말해 왔다. 현재도 수정 버전은 없다.
이런 유형이 반복되는 이유
“모델 파일을 불러오면 그들의 코드를 실행한다”는 것은 Python ML 생태계에서 가장 오래된 위험이며, pickle은 여전히 그중 상당수의 기본 직렬화 방식이다. 이 사례가 교훈적인 이유는 실패가 코드가 아니라 기록 관리에 있었기 때문이다. 2년 된 권고문이 살아 있는 sink를 해결된 것으로 표시했고, 대부분의 조직이 의존하는 자동화 도구는 이를 그대로 믿었다.
