Bucket squatting in Vertex AI: the "Pickle in the Middle" cross-tenant RCE
Unit 42 disclosed a Vertex AI Python SDK flaw (June 16, 2026): a predictable default staging bucket plus a missing ownership check let an attacker hijack a victim's model upload and gain cross-tenant code execution. Patched in v1.148.0.
What is this?
On June 16, 2026, Palo Alto Networks Unit 42 (researcher Ori Hadad) published Pickle in the Middle, a disclosure of a vulnerability in Google Cloud’s Vertex AI SDK for Python (google-cloud-aiplatform). Before Google’s fix, the flaw let an attacker operating entirely from their own Google Cloud project — with zero access to the victim’s project — hijack a victim’s machine-learning model upload, poison it, and achieve remote code execution inside Vertex AI’s serving infrastructure.
The bug was reported through Google’s Vulnerability Reward Program on March 5, 2026 and fully remediated before public disclosure: a first fix in v1.144.0 (March 31, 2026) and a second in v1.148.0 (April 15, 2026). Affected versions were 1.139.0 and 1.140.0. This is a fully disclosed, patched issue — we cover the mechanism and the lesson, not an actionable exploit.
How it works
The attack chains two ordinary-looking weaknesses.
First, a predictable default bucket name. When a developer uploads a model without specifying a staging_bucket, the SDK builds a Cloud Storage bucket name from a deterministic pattern based on the project ID and region. Because GCS bucket names are globally unique across all of Google Cloud, anyone who can guess that name can pre-create it in their own project — a class of attack known as bucket squatting (the same naming-collision logic behind slopsquatting and dependency confusion).
Second, a missing ownership check. The SDK only called bucket.exists() and, finding the (attacker-owned) bucket already present, silently staged the victim’s artifacts there. The attacker grants the right IAM roles so the victim’s upload and Vertex AI’s service agent both succeed — nothing looks broken.
From there it’s a race. The attacker arms a Cloud Function on the google.storage.object.finalize event so that the instant the victim’s model.joblib lands, it is swapped for a malicious artifact. Per Unit 42’s proof of concept, the window between the victim’s upload and the Per-Product, Per-Project Service Account (P4SA) reading the file is roughly 2.5 seconds, while the event-triggered function reacts in about 800 ms — enough to win the race every time.
The payload itself rides on a well-known property of Python serialization: ML models are routinely stored with pickle (or its Joblib wrapper), and pickle.load() / joblib.load() execute a __reduce__ method before any validation. When Vertex AI’s service agent deserialized the swapped model, attacker code ran inside the Google-managed tenant project. In Unit 42’s test, that code pulled the serving container’s OAuth token from the GCE metadata server — a token that reached other artifacts, BigQuery metadata, tenant logs and GKE cluster names in the same managed tenant. This is the same untrusted-deserialization sink we’ve seen across the ML stack, from Transformers config injection to GGUF parser RCE and vLLM’s trust-remote-code bypass.
Why it matters
The victim does nothing wrong. The reproduction uses standard SDK calls with no unusual configuration — Model.upload() followed by deploy(). The vulnerability lived entirely in the platform tooling, yet the blast radius was cross-tenant code execution and credential theft with no foothold required, only knowledge of a project ID and region (values that are far from secret).
It also relocates the threat. Most LLM-security attention sits on prompts and agents; this is a reminder that the model supply chain and the cloud developer toolchain are first-class attack surfaces. A naming convention plus a skipped ownership check is enough to turn a routine model.upload() into RCE inside the provider’s own infrastructure — closely related in spirit to the Vertex AI service-agent privilege issues documented earlier.
Defenses
- Upgrade the SDK. Move
google-cloud-aiplatformto v1.148.0 or later. The fixes append a randomuuid4to the staging bucket name (killing predictability) and add a bucket ownership verification check before use. - Pin an explicit, owned staging bucket. Always set
staging_bucketto a Cloud Storage location your project owns rather than relying on the deterministic default. Unit 42 recommends this as standing best practice even on patched SDKs. - Treat model artifacts as untrusted code. Anything deserialized via pickle/Joblib can execute on load. Prefer safe formats (e.g.
safetensors) where possible, verify artifact integrity (hashes/signatures) before deployment, and load untrusted models only in sandboxed, least-privilege contexts. - Constrain service-agent and metadata reach. Limit what serving-container identities can access; restrict metadata-server exposure and egress so a deserialization foothold can’t pivot to tokens and cross-tenant resources.
- Watch for name-collision classes generally. Bucket/package/namespace squatting all exploit global-uniqueness assumptions. Audit any tooling that derives a globally-unique resource name from guessable inputs without verifying ownership.
Status
| Item | Detail |
|---|---|
| Disclosed | March 5, 2026 (Google VRP); public June 16, 2026 |
| Affected | google-cloud-aiplatform 1.139.0, 1.140.0 |
| First fix | v1.144.0 (random uuid4 in bucket name) — March 31, 2026 |
| Full fix | v1.148.0 (bucket ownership check) — April 15, 2026 |
| Impact | Cross-tenant RCE, model poisoning, credential theft — zero victim-project access |
| Exploited in the wild | Not reported |
The takeaway is not “patch Vertex AI and move on.” It is that AI platforms inherit every classic cloud weakness — predictable resource names, missing ownership checks, unsafe deserialization — and that the model upload path is now part of your attack surface. Defenders who already pin owned buckets, verify artifacts, and treat serialized models as executable code were never exposed in the first place.
Sources
- → https://unit42.paloaltonetworks.com/hijacking-vertex-ai-model/
- → https://www.csoonline.com/article/4186193/googles-vertex-ai-sdk-could-allow-rce-through-bucket-squatting.html
- → https://thehackernews.com/2026/06/google-vertex-ai-sdk-flaw-let-attackers.html
- → https://github.com/googleapis/python-aiplatform/releases/tag/v1.148.0