CVE-2026-68772 Overview
CVE-2026-68772 is a remote code execution vulnerability in ZenML 0.94.6 that affects the CloudpickleMaterializer component. The flaw stems from unsafe deserialization [CWE-502] in the cloudpickle.load() call within cloudpickle_materializer.py. Attackers with write access to a shared artifact store can replace a stored artifact.pkl file with a crafted cloudpickle payload. When any user or pipeline materializes the artifact, the malicious __reduce__ method executes arbitrary system commands in the victim's context.
Critical Impact
Any user or automated pipeline that loads a tampered artifact executes attacker-controlled code, enabling full compromise of ZenML worker environments and downstream ML infrastructure.
Affected Products
- ZenML 0.94.6
- ZenML CloudpickleMaterializer component
- Deployments using shared artifact stores with write access for multiple principals
Discovery Timeline
- 2026-08-07 - CVE-2026-68772 published to NVD
- 2026-08-08 - Last updated in NVD database
Technical Details for CVE-2026-68772
Vulnerability Analysis
ZenML uses materializers to serialize and deserialize pipeline artifacts. The CloudpickleMaterializer writes objects as cloudpickle byte streams to the configured artifact store and reloads them on demand. The load path invokes cloudpickle.load() directly against the stored file without verifying the origin or integrity of the bytes.
Python's pickle protocol allows objects to define a __reduce__ method that specifies a callable and arguments used to reconstruct the object. During deserialization, the interpreter invokes that callable. An attacker who controls the pickle contents can therefore trigger arbitrary function calls, including os.system, subprocess.Popen, or module imports.
Exploitation requires write access to the shared artifact store used by the pipeline. In multi-tenant ML platforms and shared cloud object stores, this precondition is often satisfied by low-privileged data scientists or CI service accounts.
Root Cause
The root cause is missing integrity verification for artifact payloads. Materializers accepted any bytes present at the artifact URI and passed them to cloudpickle.load(). No content hash was recorded at write time or validated at read time, so a swapped file was indistinguishable from a legitimate artifact.
Attack Vector
An attacker with write permission to the artifact store replaces artifact.pkl for an existing artifact version with a malicious cloudpickle payload. The next pipeline run or user that materializes the artifact triggers cloudpickle.load(), which invokes the attacker's __reduce__ handler and executes commands on the host running the ZenML step. See the VulnCheck Advisory for ZenML for advisory details.
# Security patch in src/zenml/artifacts/utils.py - Validate cloudpickle content hash (#5103)
data_type=artifact.data_type,
uri=artifact.uri,
artifact_store=artifact_store,
+ expected_content_hash=artifact.content_hash,
)
Source: GitHub Commit bbf8496
# Security patch in src/zenml/materializers/base_materializer.py
"""
self.uri = uri
self._artifact_store = artifact_store
+ # Content hash recorded for the artifact version, set by the loading
+ # machinery before `load` so materializers can validate the stored data.
+ self.expected_content_hash: Optional[str] = None
@property
def artifact_store(self) -> BaseArtifactStore:
Source: GitHub Commit bbf8496. The patch introduces an expected_content_hash propagated from the artifact metadata into the materializer so that the stored bytes can be validated before deserialization.
Detection Methods for CVE-2026-68772
Indicators of Compromise
- Modifications to artifact.pkl files in shared artifact stores made by principals other than the original pipeline run identity.
- Unexpected outbound network connections or shell processes spawned from ZenML worker containers immediately after a pipeline step loads an artifact.
- ZenML step processes invoking os.system, subprocess, or /bin/sh shortly after cloudpickle.load() execution.
Detection Strategies
- Enable object-store audit logging (for example, S3 or GCS access logs) and alert on PutObject operations targeting existing artifact.pkl paths outside of pipeline execution windows.
- Instrument ZenML workers with process-lineage telemetry to flag child processes of the Python interpreter that do not match expected ML workloads.
- Compare stored artifact hashes against the metadata store on load; treat mismatches as suspected tampering.
Monitoring Recommendations
- Baseline the set of identities permitted to write to each artifact store bucket or prefix and alert on deviations.
- Monitor pipeline step containers for command execution patterns consistent with reverse shells or credential harvesting.
- Correlate ZenML pipeline logs with cloud storage access logs to identify writes that lack a matching pipeline run ID.
How to Mitigate CVE-2026-68772
Immediate Actions Required
- Upgrade ZenML to a release containing the fix from pull request #5103 that adds artifact content hash validation.
- Restrict write access on shared artifact stores to trusted pipeline execution identities only; revoke broad write grants from user or CI accounts.
- Inventory existing artifact.pkl files and re-hash them against metadata to identify prior tampering before resuming pipelines.
Patch Information
The fix is delivered in GitHub Pull Request #5103 and merged as commit bbf8496. The patch records a content hash for each artifact version and propagates an expected_content_hash into the materializer, allowing the loader to reject bytes that do not match the recorded hash before invoking cloudpickle.load(). Refer to the ZenML repository for release notes.
Workarounds
- Enforce object-store bucket policies that limit write permissions on artifact paths to the ZenML orchestrator service identity.
- Replace CloudpickleMaterializer with format-specific materializers (for example, JSON, Parquet, or Numpy) for artifact types that do not require arbitrary Python object serialization.
- Run pipeline steps in short-lived, network-restricted sandboxes so that any code execution from a poisoned artifact has minimal blast radius.
# Restrict artifact store writes to the ZenML orchestrator role (AWS S3 example)
aws s3api put-bucket-policy --bucket zenml-artifacts --policy '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"NotPrincipal": {"AWS": "arn:aws:iam::ACCOUNT_ID:role/zenml-orchestrator"},
"Action": ["s3:PutObject", "s3:DeleteObject"],
"Resource": "arn:aws:s3:::zenml-artifacts/*"
}
]
}'
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

