# Pickle in the Middle: Vertex AI Model Upload Hijacking via GCS Bucket Squatting Enables Cross-Tenant RCE (google-cloud-aiplatform v1.139.0/v1.140.0)

> Unit 42 disclosed a cross-tenant remote code execution flaw in the Google Cloud Vertex AI SDK for Python (google-cloud-aiplatform). The SDK deterministically derived the default staging bucket name and only checked the bucket's existence, not its ownership, letting an attacker who knows a victim's project ID pre-create ("squat") the predictably-named bucket and replace model artifacts during a ~2.5-second race window. Joblib/pickle deserialization of the poisoned model.joblib then executes attacker code inside Vertex AI's managed serving infrastructure with no initial access to the victim project.

- **Published:** 2026-06-16T00:00:00Z
- **Last reviewed:** 2026-06-16T00:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-0825
- **ID:** TL-2026-0825
- **Severity:** HIGH
- **Category:** VULNERABILITY
- **Status:** PATCHED
- **Detections:** 9 · **IOCs:** 23 (full data via the Threadlinqs MCP server — Purple tier)

## Description

Unit 42 (Palo Alto Networks) researchers identified a cross-tenant remote code execution (RCE) vulnerability in the Google Cloud Vertex AI SDK for Python (PyPI package google-cloud-aiplatform), affecting versions 1.139.0 and 1.140.0. The root cause lives in gcs_utils.py, in the stage_local_data_in_gcs() helper, which constructs the default staging bucket name deterministically as `{project}-vertex-staging-{location}` (for example, "my-project-vertex-staging-us-central1"). When a developer runs standard SDK upload code without explicitly specifying a custom staging_bucket, the SDK derives this name from the caller's project ID and region. Critically, the vulnerable code path used `if not staging_bucket.exists():` to decide whether to create the bucket — it verified only that the bucket existed, never that the caller (or Google's own service agents) actually owned it.

Because project IDs are frequently discoverable and bucket names are globally unique within Google Cloud Storage (GCS), an attacker who knows or guesses a target project ID can pre-register ("squat") the predictably-named staging bucket inside the attacker's own GCP project before the victim ever uploads a model. The attacker grants permissive IAM roles on the squatted bucket (roles/storage.legacyBucketReader, roles/storage.objectCreator, roles/storage.objectViewer) so that the victim's tooling and Google's Vertex AI service agents can read and write to it.

To win the race, the attacker deploys a Cloud Function triggered on the `google.storage.object.finalize` event. When the victim's SDK uploads its model artifact (model.joblib, staged under the vertex_ai_auto_staging/ prefix), the Cloud Function fires and swaps the legitimate artifact for a malicious pickle within a narrow window. Unit 42 measured the timeline: T+0 ms the victim SDK uploads model.joblib (601 bytes); T+804 ms the Cloud Function detects the new object; T+1,433 ms the function replaces the model (601 → 2,945 bytes); T+2,460 ms the Vertex AI Service Agent reads the now-poisoned model — a total exploitation window of roughly 2.5 seconds.

When the victim subsequently deploys the model to an endpoint, the serving container loads the artifact with joblib.load(), which deserializes the pickled Python object. The malicious artifact carries a crafted `__reduce__` method, the canonical pickle code-execution primitive, so deserialization executes arbitrary attacker code inside Vertex AI's managed serving environment. Execution occurs in the context of Vertex AI service identities — the Per-Product Per-Project Service Account (P4SA) `service-PROJECT_NUMBER@gcp-sa-aiplatform.iam.gserviceaccount.com` and the tenant-project custom online prediction account `custom-online-prediction@<tenant-project>.iam.gserviceaccount.com`.

Post-exploitation, Unit 42 demonstrated that an exfiltrated access token carrying the broad cloud-platform OAuth scope enabled cross-deployment model theft from GCS buckets, enumeration of and access-control reads against BigQuery datasets and tables, and Cloud Logging access that revealed GKE cluster names, deployment details, and internal container image URIs — a substantial cross-tenant blast radius from a single poisoned model.

The issue was responsibly disclosed to Google on March 5, 2026, prioritized as top severity, and remediated in two stages: v1.144.0 (March 31, 2026) appended a randomly generated uuid4 value to the staging-bucket naming routine to break name predictability, and v1.148.0 (April 15, 2026) added an explicit bucket ownership verification check to gcs_utils.py. Google recommends all developers upgrade to v1.148.0 or later. No CVE, CVSS score, network IOCs, or threat-actor attribution were stated in the source research; none are invented here. This is a proof-of-concept disclosure with no observed in-the-wild exploitation reported.

## MITRE ATT&CK

- T1583 Acquire Infrastructure
- T1587 Develop Capabilities
- T1608 Stage Capabilities
- T1195 Supply Chain Compromise
- T1199 Trusted Relationship
- T1059 Command and Scripting Interpreter
- T1648 Serverless Execution
- T1036 Masquerading
- T1078 Valid Accounts
- T1528 Steal Application Access Token
- T1552 Unsecured Credentials
- T1526 Cloud Service Discovery
- T1580 Cloud Infrastructure Discovery
- T1619 Cloud Storage Object Discovery
- T1082 System Information Discovery
- T1530 Data from Cloud Storage
- T1213 Data from Information Repositories
- T1567 Exfiltration Over Web Service
- T1537 Transfer Data to Cloud Account

## Sources

- [Pickle in the Middle – Hijacking Vertex AI Model Uploads for Cross-Tenant RCE](https://unit42.paloaltonetworks.com/hijacking-vertex-ai-model/)
- [Google Cloud Vertex AI Vulnerability Exposes Sensitive Data to Attackers](https://cyberpress.org/google-cloud-vertex-ai-vulnerability/)
- [Double Agents: Exposing Security Blind Spots in GCP Vertex AI](https://unit42.paloaltonetworks.com/double-agents-vertex-ai/)
- [ModeLeak: Privilege Escalation to LLM Model Exfiltration in Vertex AI](https://unit42.paloaltonetworks.com/privilege-escalation-llm-model-exfil-vertex-ai/)
- [Model Namespace Reuse: An AI Supply-Chain Attack Exploiting Model Name Trust](https://unit42.paloaltonetworks.com/model-namespace-reuse/)
- [google-cloud-aiplatform on PyPI (fixed releases v1.144.0 / v1.148.0)](https://pypi.org/project/google-cloud-aiplatform/)

## Full data

Detection queries (Splunk SPL / Microsoft KQL / Sigma) and IOC values require the Threadlinqs MCP server (Purple tier): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-0825
