T09 · Insecure Skill Coding Practices
- Location
scripts/predict.py:36- Finding
Unsafe Deserialization of Local Model Artifacts
- Content
View full analysis
Vulnerability Details
File Location:
scripts/predict.py:36-41
Vulnerability Type: Unsafe pickle-compatible deserialization
Risk Level: MediumVulnerable Code
python def load_model(): model = joblib.load(config.MODEL_PATH) with open(config.FEATURE_PATH) as f: feature_names = json.load(f) scaler = joblib.load(config.SCALER_PATH) return model, feature_names, scalerThe affected artifact paths are defined in
scripts/config.py:45-47:python MODEL_PATH = os.path.join(MODEL_DIR, "xgb_stock_model.pkl") FEATURE_PATH = os.path.join(MODEL_DIR, "feature_names.json") SCALER_PATH = os.path.join(MODEL_DIR, "scaler.pkl")Technical Analysis
joblib.load()relies on Python's pickle-compatible deserialization mechanism. Pickle artifacts can contain object-reconstruction instructions that invoke arbitrary Python callables during loading. Therefore, loading an attacker-controlled.pklfile is equivalent to executing untrusted code.The model and scaler are normally generated locally by
scripts/train.py, so this finding does not indicate intentionally embedded malicious behavior. However,load_model()performs no signature, checksum, ownership, permission, symlink, or provenance validation before deserializing the files. A replaced artifact in a shared, compromised, or attacker-writable project directory could consequently execute code when prediction starts.Attack Path
- An attacker gains the ability to replace either
scripts/models/xgb_stock_model.pklorscripts/models/scaler.pkl, such as through a compromised project archive, shared writable workspace, poisoned artifact distribution, or another process with write access. - The attacker creates a malicious pickle-compatible artifact whose reconstruction routine executes an operating-system command or arbitrary Python code.
- A user runs
python3 predict.py, or runspython3 main.pywith th ...[truncated 1181 chars]
- An attacker gains the ability to replace either
- Remediation
View remediation
Remediation Suggestions
-
Replace executable serialization formats
- Store the XGBoost model using a non-pickle model format, such as JSON or UBJSON.
- Store scaler parameters and feature metadata in validated JSON or another non-executable data format.
- Reconstruct the scaler from validated numeric fields rather than deserializing a Python object.
-
Authenticate artifacts
- Generate a cryptographic digest or digital signature when training completes.
- Verify the digest or signature before loading either artifact.
- Store the trusted verification key or expected digest separately from the writable artifact directory.
-
Restrict filesystem access
- Place model artifacts in a directory writable only by the owning user.
- Reject symbolic links and files with unexpected ownership or group/world-writable permissions.
- Open and validate artifacts using race-resistant filesystem operations where supported.
-
Validate artifact provenance and schema
- Record model version, expected type, library versions, feature count, and training metadata.
- Reject artifacts with unexpected metadata or incompatible versions.
- Do not accept downloaded or user-supplied
.pklfiles unless they originate from an authenticated source.
-
Document the trust boundary
- Clearly warn that
jobliband pickle artifacts must never be loaded from untrusted sources. - Treat models bundled in third-party archives or copied from shared locations as executable content.
- Clearly warn that
-
Use containment as defense in depth
- Run prediction under a dedicated, least-privileged account or isolated container.
- Limit filesystem access, environment secrets, and outbound network access available to the prediction process.
-
