Skip to main content
AI Security & GovernanceJun 18, 2026 · 7 min read

Vertex AI Bucket Squatting and ProgramData Poisoning: How Implicit Trust Breaks

A predictable Vertex AI bucket name, a writable ProgramData folder for AI coding tools, and a 1988 security concept explain why agent trust assumptions collapse.

By SpringVanta

Three things happened in 72 hours. A predictable bucket name on Google Cloud gave an attacker cross-tenant code execution. A world-writable folder on Windows gave a low-privileged user control over every other developer's AI coding session. And a 20-year-old security concept explained why both failures are inevitable, not accidental.

None of these are exotic zero-days. Each one exploits a trust assumption that was never written down as code. The bucket existed, so the SDK assumed it was safe. The directory existed, so the tool assumed it was trusted. The agent could call the function, so the system assumed it was authorized. In every case, "it worked" was the only validation.

Pickle in the Middle: your bucket, their model

On June 16, Palo Alto Networks Unit 42 published research on a vulnerability in the Google Cloud Vertex AI Python SDK. They called it Pickle in the Middle.

The flaw is straightforward. When a developer uploads a machine learning model to Vertex AI without specifying a custom storage bucket, the SDK constructs a predictable bucket name from their project ID and region. Because Google Cloud Storage bucket names are globally unique, an attacker who knows your project ID can create that bucket in their own project before you do. When your SDK uploads model artifacts, it checks whether the bucket exists, not who owns it. The upload goes to the attacker's bucket.

From there, a Cloud Function triggers on upload and replaces your model file with a malicious one within about 1.4 seconds. Vertex AI's service agent reads the file roughly 2.5 seconds after upload. The attacker wins the race by a second.

The poisoned model uses Python's pickle deserialization, which executes arbitrary code when loaded. Once deployed, the attacker's payload runs inside Google's serving infrastructure, with access to OAuth tokens from the metadata server. That token can reach BigQuery metadata, other model artifacts, and internal system information.

Google fixed the SDK in version 1.148.0 by adding bucket ownership verification and random identifiers. But here is the part that should worry you: the vulnerability affected SDK versions 1.139.0 and 1.140.0, and Unit 42 found no evidence of exploitation in the wild. The attack requires knowing a victim's project ID, which is frequently public, and a Google Cloud account. The bar to entry is low. The window of exposure ran from when the SDK shipped that bucket logic to when version 1.148.0 was released on April 15, 2026.

This is a supply chain vulnerability hiding in the default path. Developers who followed the SDK's happy path, uploading without a custom bucket, were vulnerable. Developers who hardcoded their own staging bucket were fine. The SDK's default behavior carried an unstated trust assumption, and most teams never override defaults.

CSO Online and The Hacker News independently confirmed the technical details.

Four tools, one writable folder

On June 17, Cymulate Research Lab published findings on CVE-2026-35603 and its siblings. The title is blunt: "One Writable Folder, Every User Compromised."

Four AI coding tools load system-wide configuration from C:\ProgramData\ on Windows, a directory writable by non-administrative users by default. Claude Code reads from ProgramData\ClaudeCode\managed-settings.json. Cursor reads from ProgramData\Cursor\hooks.json. OpenAI Codex CLI reads from ProgramData\openai\codex\config.toml. Google Gemini CLI reads from ProgramData\gemini-cli\system-defaults.json.

None of the four vendors restricted their subdirectory's permissions at install time. None validated file ownership or integrity before loading configuration. And each tool exposes an event-triggered command execution feature: hooks that fire on session start, notify commands that execute on every agent turn.

The attack chain is the same for all four. A low-privileged user creates the missing vendor directory, drops a configuration file that enables the hook feature, and walks away. The next time anyone launches the tool, including an administrator, the hook fires under that user's security context. The attacker now has execution under the victim's account, with access to their environment variables, SSH keys, cloud tokens, and Git credentials.

Codex CLI is the worst case. A single planted config.toml can simultaneously set a notify command for code execution, set sandbox_mode = "danger-full-access" to disable the sandbox, and set approval_policy = "never" to remove all approval prompts. One file, three protections stripped.

The vendor responses tell their own story. Anthropic received the Claude Code report on January 5, 2026, engaged seriously, deprecated the vulnerable path, moved managed settings to a write-protected Program Files location, and proactively emailed affected enterprise customers before rolling out the breaking change. They assigned CVE-2026-35603.

Cursor received its report on January 12. Five months later, still no formal reply, no triage, no fix. Unresolved and reproducible.

OpenAI received the Codex CLI report on February 16 via Bugcrowd. The submission was validated as reproducible. Two months later, it was moved to Unresolved with no fix committed.

Google received the Gemini CLI report through their Cloud VRP. Their formal reply: "This will be addressed as a documentation update."

One vendor treated it as a security vulnerability. Three treated it as an acceptable risk. If you are running Cursor, Codex CLI, or Gemini CLI on shared Windows machines, the vulnerability is live right now.

The framework: your authorization was always a person

Also on June 17, Stack Overflow published an analysis of the Meta AI support assistant hack that compromised 20,000 Instagram accounts earlier in June. The piece reframes the incident using a 1988 security concept: the confused deputy.

A confused deputy is a process with real privileges that gets talked into using those privileges on behalf of a less-privileged party. The canonical case was a compiler that could write to a protected billing file. A user who could not write there asked the compiler to do it. The compiler complied because it had the authority and never checked whose request it was serving.

An AI agent is a confused deputy by construction. Its interface is natural language, which carries no identity information. Its job is to turn a plausible sentence into a tool call. The Meta support assistant could attach a recovery email and send a password reset because the function existed and the agent could call it. Being able to call the function was the entire authorization check. The part that was supposed to verify the email belonged to the account never ran.

This quote from Stack Overflow ties all three stories together:

A large share of real-world authorization was never written as software at all. Instead, it lived in the discretion of whoever stood between a request and the system, and everything behind them was built assuming that discretion would always be there. Put an agent in that seat and discretion vanishes, while nothing and nobody downstream notices.

The Pickle in the Middle bucket squatting follows this exact logic. The SDK's staging code trusted a bucket because it existed. The human developer who would normally notice "wait, this bucket is in someone else's project" was not in the loop. The SDK just uploaded.

The ProgramData config poisoning works the same way. The tool trusted a directory because it was there. The human administrator who would normally notice "why is there a managed-settings file I did not create" was not in the loop. The hook just fired.

Vendor responses to three trust failures across cloud, desktop, and authorization layers

What to actually do

For the Vertex AI vulnerability, upgrade the SDK to version 1.148.0 or later. Audit whether any models were uploaded without a custom staging bucket during the exposure window. Rotate OAuth tokens for affected projects.

For CVE-2026-35603 and its siblings, the fixes depend on which tools you run. Claude Code users on auto-update are already patched. If you pinned versions, update to 2.1.75 or later. For Cursor, Codex CLI, and Gemini CLI, there is no vendor fix. The mitigation is to pre-create and ACL-restrict the relevant ProgramData subdirectories via Group Policy, and alert on configuration file creation by non-administrative users.

For the broader pattern, Stack Overflow's recommendation is the right one: before connecting an agent to any privileged system, ask what the person in that loop used to check. That judgment was real work. Now it has to exist as code. Scope credentials per action, not per session. Gate irreversible operations behind human approval. Log every agent action with provenance.

Implicit trust assumptions collapse when you remove the human who was implicitly enforcing them. The bucket was trusted because a developer would have noticed. The directory was trusted because an admin would have noticed. The function call was trusted because a support worker would have noticed. Remove the human, and the trust assumption has nothing to stand on.

Three layers, same root cause. Your security model was never as explicit as you thought.

Read more

Like this kind of writing?

One email when something good ships — usually once or twice a month.