Google Cloud Vertex AI Python SDK Bucket-Squatting ("Pickle in the Middle") Enables Cross-Tenant Model Hijacking and RCE

Google Cloud Vertex AI Python SDK Bucket-Squatting ("Pickle (TL-2026-0880), also tracked as Pickle in the Middle, is a high-severity software vulnerability, first published 2026-06-19. It has no confirmed attribution, affects Google Vertex AI Python SDK (google-cloud-aiplatform), maps to 18 MITRE ATT&CK techniques (T1036, T1059, T1069), and is covered by 9 detection rules and 19 indicators of compromise.

Key facts for TL-2026-0880

Threat ID
TL-2026-0880
Also known as
Pickle in the Middle
Severity
HIGH
Status
PATCHED
Category
VULNERABILITY
First published
2026-06-19
Last reviewed
2026-06-19
Attribution confidence
NONE
Motivation
UNKNOWN
Target sectors
technology, artificial-intelligence, machine-learning, cloud-services, financial, healthcare
Target regions
Global
Detection rules
9
Indicators of compromise
19

Malware and tooling in Google Cloud Vertex AI Python SDK Bucket-Squatting ("Pickle

Malware and tooling: Attacker-controlled GCP Cloud Function (finalize-triggered swapper)

Google Cloud's Vertex AI Python SDK (google-cloud-aiplatform 1.139.0/1.140.0) generated predictable Google Cloud Storage staging-bucket names from the project ID and region and validated only bucket existence, not ownership. Attackers could pre-create the expected bucket ("bucket squatting"), silently capture and swap a victim's model artifacts, and achieve cross-tenant remote code execution inside Vertex AI serving containers via pickle/joblib deserialization within a ~2.5-second race window. Resolved by UUID-randomized bucket names (1.144.0) and explicit ownership verification (1.148.0).

How Google Cloud Vertex AI Python SDK Bucket-Squatting ("Pickle works

Unit 42 (Palo Alto Networks) researcher Ori Hadad disclosed a high-severity flaw in the Vertex AI Python SDK (google-cloud-aiplatform) dubbed "Pickle in the Middle." When a developer calls model/training APIs (e.g. aiplatform.init() and Model.upload()) without explicitly setting a staging bucket, the SDK's staging logic in gcs_utils.py — specifically the stage_local_data_in_gcs() flow — deterministically constructs a Google Cloud Storage bucket name as "<project>-vertex-staging-<location>" (e.g. my-project-vertex-staging-us-central1). The SDK then called staging_bucket.exists() and proceeded if the bucket merely existed, without verifying that the bucket belonged to the caller's project. Because GCS bucket names are a single global namespace, an attacker can predict and pre-create the victim's expected bucket in an attacker-controlled project ("bucket squatting") and open it with an allAuthenticatedUsers read/write IAM policy.

The full chain: (1) the attacker pre-creates the predicted bucket and grants allAuthenticatedUsers write access; (2) the attacker deploys a Cloud Function bound to a google.storage.object.finalize trigger on that bucket; (3) the victim runs an unconfigured Model.upload(), and the SDK silently stages the model artifact into the attacker's bucket; (4) the finalize-triggered Cloud Function swaps the legitimate artifact for a poisoned pickle within milliseconds; (5) the victim deploys the model with endpoint.deploy(); (6) the Vertex AI serving container calls joblib.load()/pickle.load() on the swapped artifact, executing the attacker's payload. Python's pickle format invokes a class's __reduce__ method during deserialization, so an attacker-controlled pickle runs arbitrary Python the instant it is loaded — before any validation.

The race is narrow but reliable: in Unit 42's proof of concept the victim's 601-byte model was uploaded at T+0ms, the Cloud Function detected the finalize event at T+804ms, replaced it with a 2,945-byte poisoned artifact at T+1,433ms, and Vertex AI's service agent read the poisoned model at T+2,460ms — a ~2.5-second window requiring near-real-time attacker automation. Post-exploitation, code running in the serving container queried the GCP instance metadata server and exfiltrated the token of the per-tenant service account custom-online-prediction@<tenant-project>.iam.gserviceaccount.com, which enabled same-tenant model theft from other deployments, BigQuery dataset/table enumeration and ACL access, and broader reconnaissance of tenant infrastructure (GKE clusters, container image URIs, logging). No exploitation in the wild was observed. Google rated the issue High under its Vulnerability Reward Program and shipped two fixes: UUID-randomized bucket naming in 1.144.0 (2026-03-31) and explicit bucket ownership verification in 1.148.0 (2026-04-15).

MITRE ATT&CK techniques used in TL-2026-0880

Defense Evasion

T1036 Masquerading

Execution

T1059 Command and Scripting Interpreter; T1204 User Execution; T1648 Serverless Execution

Discovery

T1069 Permission Groups Discovery; T1526 Cloud Service Discovery; T1580 Cloud Infrastructure Discovery

Lateral Movement

T1080 Taint Shared Content

Initial Access

T1195 Supply Chain Compromise; T1199 Trusted Relationship

Credential Access

T1528 Steal Application Access Token; T1552 Unsecured Credentials

Collection

T1530 Data from Cloud Storage

Exfiltration

T1537 Transfer Data to Cloud Account

Impact

T1565 Data Manipulation

Resource Development

T1583 Acquire Infrastructure; T1587 Develop Capabilities; T1608 Stage Capabilities

Affected products and versions in Google Cloud Vertex AI Python SDK Bucket-Squatting ("Pickle

  • Google — Vertex AI Python SDK (google-cloud-aiplatform)
    Vulnerable versions: 1.139.0; 1.140.0
    Fixed in: 1.144.0 (UUID bucket naming); 1.148.0 (ownership verification)

Remediation for Google Cloud Vertex AI Python SDK Bucket-Squatting ("Pickle

Patches

  • google-cloud-aiplatform 1.144.0 (2026-03-31) — UUID-randomized staging bucket names.
  • google-cloud-aiplatform 1.148.0 (2026-04-15) — explicit bucket ownership verification.

Immediate actions

  • Upgrade google-cloud-aiplatform to 1.148.0 or later (UUID bucket naming + ownership verification).
  • Explicitly set a staging bucket you own via aiplatform.init(staging_bucket=...) / the staging_bucket argument instead of relying on SDK defaults.
  • Audit GCS for buckets matching the pattern <project>-vertex-staging-<location> that you do not own, and for any unexpected allAuthenticatedUsers/allUsers grants.

Workarounds

  • Always pass an explicit, owned staging_bucket to SDK init/upload calls.
  • Restrict who may create GCS buckets and forbid public/allAuthenticatedUsers IAM on staging buckets.

Longer-term hardening

  • Treat all model artifacts as untrusted input; prefer safetensors or non-executable serialization over pickle/joblib for model exchange.
  • Enforce bucket ownership and project-scoped IAM on all ML staging paths; deny allAuthenticatedUsers/allUsers on storage.
  • Add integrity verification (hashing/signing) of model artifacts between upload and deployment.
  • Constrain Vertex AI serving service-account permissions and metadata-server access (least privilege; workload identity).

Weaknesses (CWE) in Google Cloud Vertex AI Python SDK Bucket-Squatting ("Pickle

CWE-340, CWE-502, CWE-345, CWE-639

Timeline of Google Cloud Vertex AI Python SDK Bucket-Squatting ("Pickle

  • Unit 42 (Ori Hadad) reports the predictable-bucket-name / missing-ownership-validation flaw in the Vertex AI Python SDK to Google.
  • Google assigns the report top priority.
  • Google acknowledges the issue and assigns top severity under its Vulnerability Reward Program (rated High).
  • First production fix shipped in google-cloud-aiplatform 1.144.0: staging bucket names randomized with UUIDs.
  • Second production fix shipped in google-cloud-aiplatform 1.148.0: explicit bucket ownership verification added.
  • GitLab Advisory Database publishes an advisory for the PyPI google-cloud-aiplatform package covering the predictable-staging-bucket / missing-ownership-validation flaw.
  • Unit 42 publishes a full proof-of-concept walkthrough: victim uploads model.joblib (601 bytes) at T+0ms, the finalize-triggered Cloud Function detects it at T+804ms and swaps in a 2,945-byte poisoned artifact at T+1,433ms, and the Vertex AI service agent reads the poisoned model at T+2,460ms.
  • Unit 42 publishes the 'Pickle in the Middle' research detailing bucket squatting, the ~2.5s race window, and cross-tenant RCE; no exploitation in the wild observed.
  • Secondary outlets (Cyber Security News, The Hacker News, CSO Online, SC Media, GBHackers) cover the disclosure.

Sources cited for Google Cloud Vertex AI Python SDK Bucket-Squatting ("Pickle

Threats related to Google Cloud Vertex AI Python SDK Bucket-Squatting ("Pickle

Detection coverage for TL-2026-0880

As of 2026-06-19, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-0880 across Splunk SPL, Microsoft KQL and Sigma, covering 19 indicator(s) of compromise. The whole corpus is readable without an account; a free account unlocks full detection query text in Splunk SPL, Microsoft KQL and Sigma; paid tiers add raw indicator values, correlation and the MCP server. Threadlinqs MCP server · View plans.

Threadlinqs Intelligence — Real-Time Threat Detection Platform

[ 0 threats ] [ 0 det ] [ CRIT: 0 ] [ HIGH: 0 ]
// threat_feed
$ sort --newest
Showing all threats

Latest Threats