T09 · Insecure Skill Coding Practices
Error
- Location
- ml_predictor.py:597
- Finding
- Unsafe Pickle Deserialization in Model Loading## Vulnerability Details **File Location**: `ml_predictor.py:597-612` **Vulnerability Type**: Unsafe deserialization **Risk Level**: High ### Vulnerable Code ```python def load_model(self, path: str = "lstm_model.keras"): """加载模型和 scaler""" import pickle if TF_AVAILABLE: from tensorflow.keras.models import load_model # 自动检测文件格式 if path.endswith('.h5'): from tensorflow.keras.models import load_model as load_h5 self.model = load_h5(path, compile=True) else: self.model = load_model(path) # 加载 scaler scaler_path = path.replace('.keras', '_scaler.pkl') try: with open(scaler_path, 'rb') as f: self.scaler = pickle.load(f) ``` ### Technical Analysis The `load_model()` method derives a scaler filename from a caller-provided model path and deserializes that file with `pickle.load()`. Python pickle is not a data-only format: serialized objects can define reduction operations that invoke arbitrary Python callables during deserialization. The code performs no authenticity, integrity, ownership, or trusted-directory validation before loading the scaler. Consequently, a malicious scaler file supplied alongside a model, downloaded from an untrusted source, or placed through local filesystem access can execute code before the method returns. Merely inspecting the expected object type after deserialization would not prevent exploitation because execution occurs during `pickle.load()` itself. ### Attack Path 1. An attacker creates a malicious pickle whose reduction method invokes an operating-system or Python function. 2. The attacker distributes it as the scaler associated with a model, such as `shared_model_scaler.pkl`, or replaces an existing scaler file in a writable model directory. 3. A user or integrating Agent calls `load_model("shared_model.keras")`. 4. The method derives `sha ...[truncated 816 chars]
- Remediation
- ## Remediation Suggestions 1. Do not use pickle for scaler persistence. Store data-only scaler attributes such as `mean_`, `scale_`, `var_`, and `n_features_in_` in JSON or NumPy files and reconstruct a known scaler class explicitly. 2. Treat both model and scaler files as executable or security-sensitive artifacts. Load them only from an application-controlled directory. 3. Verify artifacts using a cryptographic signature or an authenticated manifest before parsing them. A hash obtained from the same untrusted source is insufficient. 4. Reject symlinks and paths outside the approved model directory after resolving the canonical path. 5. Apply restrictive ownership and filesystem permissions to the artifact directory. 6. If backward compatibility requires pickle, clearly document that only trusted, locally generated pickle files may be loaded and isolate loading in a sandboxed process with minimal filesystem and network privileges.
