T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/deploy_model.py:20
- Finding
- Unsafe Deserialization of Untrusted Model Artifacts<![CDATA[ ## Vulnerability Details **File Location**: `scripts/deploy_model.py:20-23` **Additional Locations**: `scripts/deploy_model.py:82-83`, `references/deployment.md:47-49`, `references/deployment.md:91-93` **Vulnerability Type**: Unsafe pickle-compatible model deserialization **Risk Level**: High ### Vulnerable Code ```python def load_model(model_path): """Load trained model.""" print(f"Loading model from {model_path}") package = joblib.load(model_path) ``` The generated inference wrapper repeats the unsafe operation: ```python def __init__(self, model_path='model.joblib'): self.model = joblib.load(model_path) ``` The deployment guide also recommends unsafe model loading: ```python def load_model_for_deployment(model_path): """Load complete model package.""" package = joblib.load(model_path) return package['model'], package['feature_engineer'], package['metadata'] ``` ```python def load_pytorch_model(model_class, checkpoint_path): """Load PyTorch model for inference.""" checkpoint = torch.load(checkpoint_path, map_location='cpu') ``` ### Technical Analysis `joblib.load()` uses pickle-compatible deserialization. Pickle formats can encode calls to arbitrary Python functions through mechanisms such as `__reduce__`. Consequently, loading a maliciously constructed model artifact can execute operating-system commands before the returned object is inspected. The deployment CLI accepts a caller-provided path through `--model`, and the generated API automatically deserializes `model.joblib` during module initialization. No signature, cryptographic digest, trusted-directory restriction, ownership check, or safe serialization format is enforced. The documented `torch.load()` call presents a similar risk when loading legacy or attacker-controlled checkpoints because it does not explicitly restrict loading to tensor weights through an appropriate safe-loading mode. ### Attack Path 1. An attacker creates a maliciou ...[truncated 1084 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not deserialize model artifacts from untrusted or user-writable locations. 2. Prefer non-executable formats such as ONNX or framework-specific safe tensor formats. 3. Digitally sign model artifacts and verify their signatures before loading. 4. Maintain an allowlist of trusted model directories and reject symlinks, unexpected owners, or group/world-writable files. 5. If pickle-compatible loading remains unavoidable, isolate it in a disposable, least-privileged sandbox without secrets, network access, or sensitive mounts. 6. For PyTorch state dictionaries, use a supported safe-loading mode such as `torch.load(..., weights_only=True)` and construct the model architecture from validated local code. 7. Perform integrity verification before deserialization; validation after `joblib.load()` is too late. 8. Run the API and deployment process as a dedicated unprivileged account. ]]>
