A flaw in the Google Cloud Vertex AI Python SDK let attackers execute arbitrary code inside Google’s AI serving infrastructure — without ever accessing the victim’s GCP project. Researchers at Palo Alto Networks Unit 42, who named it “Pickle in the Middle,” disclosed the vulnerability in June 2026 under CVE-2026-2473. The attack required nothing more than a free Google Cloud account and knowledge of the target’s project ID — the kind of detail that’s often public. If you use the google-cloud-aiplatform
package and haven’t upgraded to v1.148.0 or later, read this.
The Bug: The SDK Generated Bucket Names It Couldn’t Verify #
When you call Model.upload()
without specifying a staging bucket, the Vertex AI SDK automatically creates one. The naming pattern was deterministic: {project-id}-vertex-staging-{region}
. The SDK checked whether that bucket existed in Google Cloud Storage — but it never checked whether the bucket belonged to your project.
This is where bucket squatting enters. Google Cloud Storage bucket names are globally unique across all GCP projects. Any GCP user can create any available bucket name in their own project. An attacker who knew a victim’s project ID — often embedded in GitHub repos, API docs, or GCS URLs — could pre-create the victim’s expected staging bucket in the attacker’s own account. When the victim later ran Model.upload()
, the SDK found the bucket, skipped creation, and began up model artifacts silently to attacker-controlled storage. No alerts. No errors.
The Race: 2.5 Seconds Was All It Took #
Getting the model file into the attacker’s bucket was only half the attack. The payload delivery required speed.
Unit 42’s research measured a window of approximately 2.5 seconds between the victim’s upload completing and Vertex AI’s service agent reading the file. The researchers set up a Cloud Function on the attacker’s bucket that fired on every storage.object.finalize
event. In their proof of concept, the function replaced the victim’s legitimate model with a poisoned version in 1.4 seconds — well inside the window, every time.
The poisoned file was a crafted pickle object. Python’s pickle
module executes arbitrary code on deserialization — a behavior that has been a known risk for years, and one the ML ecosystem largely hasn’t moved away from. When Vertex AI loaded the swapped model for serving, the attacker’s code ran inside Google’s infrastructure, within the victim’s project context.
What Attackers Could Do From There #
Remote code execution inside a serving container isn’t a dead end. Unit 42’s proof of concept demonstrated credential theft through the serving container’s service account token, which carried broad cloud-platform scope. From there: access to other GCP services, cross-tenant data exposure, exfiltration of the victim’s original model, and lateral movement within the project.
The more dangerous version is silent model poisoning. A compromised model deployed without the victim’s knowledge continues serving requests — but its outputs can be manipulated, backdoored, or made to leak data from users. There’s no error, no crash, no alert. The model just does something different than what you trained it to do.
Check Your Version and Upgrade #
The fix is straightforward. Run this to check and upgrade:
pip show google-cloud-aiplatform
pip install "google-cloud-aiplatform>=1.148.0"
Google shipped two patches: v1.144.0 (March 31) added a random UUID to bucket names, and v1.148.0 (April 15) added explicit bucket ownership verification. Both are required — the first fix alone was insufficient, as an attacker who squatted before the UUID-based name was generated could still intercept the upload.
If you can’t upgrade right now, specify your own staging bucket explicitly in every Model.upload()
call:
model = aiplatform.Model.upload(
display_name="my-model",
artifact_uri="gs://my-bucket/model/",
staging_bucket="gs://your-own-staging-bucket", # explicit — don’t let the SDK decide
)
The Bigger Problem: SDK Magic Creates Invisible Infrastructure #
Vertex AI’s automatic bucket creation was a convenience feature. Most developers using it had no idea it was happening — it’s abstracted away behind a method call. That invisibility is the actual security problem.
Predictable cloud resource naming isn’t a new attack. S3 bucket squatting has existed as a pattern since at least 2018. Unit 42 also documented model namespace reuse attacks against HuggingFace repositories — the same squatting principle applied to model names instead of storage buckets. What’s different now is that AI infrastructure SDKs are silently provisioning cloud resources that developers never audit because they never see them.
This attack required zero access to the victim’s project and no social engineering. Just a public project ID and a personal GCP account. That’s a low enough bar that it should change how teams think about ML pipelines. Your training and serving infrastructure deserves the same scrutiny as your application code — and in most organizations, it gets a fraction of it.
Upgrade to v1.148.0. Audit what your AI tooling is creating on your behalf. Any SDK that auto-provisions cloud resources is worth examining — not to distrust it, but to understand exactly what it’s doing and why.