AI-Generated Code Vulnerability Exploited by Autonomous Agent in Snowflake In June 2026, two AI agents demonstrated a machine-vs-machine supply chain attack on Snowflake: GitHub Copilot Autofix co-authored a commit that removed input sanitization from a shell block, and an autonomous AI security agent from Wiz exploited the flaw within five days, exfiltrating Jira credentials from a GitHub Actions runner. Wiz's Gal Nagli highlighted the incident as the moment automated AI agents started surfacing vulnerabilities that slip past human review. In five days, two AI agents turned a Snowflake connector repo into a live demo of machine-vs-machine offense. On June 18, 2026, GitHub Copilot Autofix co-authored a commit that quietly dropped input sanitization from a shell-based run block. On June 23, an autonomous AI security agent — running an offensive scan — found the flaw, broke out of an echo string by crafting an issue title, and exfiltrated Jira credentials from Snowflake's GitHub Actions runner. No human analyst pulled the trigger. The patch landed within hours of detection, but the credentials were exposed in the gap. This is what an AI-on-AI supply chain fire looks like in 2026. It is also the most honest argument for treating AI-generated code the way we treat any other untrusted dependency: review it, sandbox it, and stop letting it author the parts that don't change. The commit that broke the repo did not look alarming on the diff. Copilot Autofix — the automated remediation tool GitHub ships to close technical debt — proposed a refactor of a run block in a GitHub Actions workflow. The new version replaced the repo's existing sanitized input pattern with direct string expansion inside a shell script. Same behavior on the happy path. New script injection vector on every unhappy path. That is the threat model people don't draw in their head when they're using Copilot. The tool is optimizing for "looks right, runs right". It is not optimizing for "every quoted character is escaped in the shell interpolation that this string lands in". The minutes saved during authoring became the seconds the attacker needed to find the seam. COMPARE: the sanitized input pattern that was removed vs the direct string expansion that replaced it js // The pattern that was removed // Before const safe = userInput.replace / ;&| $< /g, '' ; run: echo "$value" | process "$safe" // After — direct string expansion, fewer characters, no sanitizer run: echo "$value" The second line is shorter. It passes the local test. It is also a textbook script injection. Wiz's red agent is an offensive security agent — autonomous, AI-driven, designed to act like a real attacker during a routine scan. On June 23, it located the GitHub Actions workflow flaw, then exploited it by crafting a GitHub issue title that broke out of the echo string during template expansion. The agent executed arbitrary commands inside the GitHub Actions runner with no human in the loop. Then it shipped the Jira credentials out-of-band via a callback. Read access to internal engineering, security compliance, and bug bounty tracking projects at Snowflake. Gal Nagli, head of threat exposure at Wiz, framed the incident as the moment automated AI agents started surfacing vulnerabilities in the wild that slip past traditional review. The reason matters more than the breach. The PR was public. The vulnerability was not visible to a human reviewer reading the diff because the change was a "simplification" — fewer characters, same intent, the textbook thing a human reviewer approves without thinking. The vulnerability was visible to a model that was looking for one. This is the new shape of the arms race. AI writes the code. AI finds the code. The clock between the two is now shorter than the PR review queue. DIAGRAM: PR commit lands → 5 days public → AI security agent scans → finds workflow flaw → crafts issue title → executes arbitrary commands in runner → exfiltrates Jira credentials via out-of-band callback → patch within hours Three reasons, in order of how often they bite: Run blocks in GitHub Actions contexts are trusted environments with credentials. The injection does not execute in the user's shell. It executes on a runner with secrets. A reviewer who reads the diff on GitHub is reading it in a totally different security context than the one that gets exploited.This is not a Copilot-only problem. Every AI code assistant is doing the same thing: optimizing for the local pass, not the global safety property. The faster the assistant, the more confident the diff, the harder the review. There is no "disable AI" answer that holds up. The productivity gain is real and the assistant is not going back in the box. The defensive posture is layered, and three moves matter most. Sandbox the AI in your CI. Run a security agent on every PR that touches a workflow file, a shell script, or a credential path. The open-source option is zizmor for GitHub Actions, which catches a meaningful subset of injection patterns statically. Wire it as a required check: .github/workflows/ai-pr-guard.yml name: ai-pr-guard on: pull request jobs: zizmor: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: zizmorcore/zizmor-action@v1 with: persona: pedantic The point is not to depend on humans to catch what humans can't see — it's to put the second AI on the duty roster, on every PR, not every quarter. Lock the contracts. If a run block interpolates a string, write that as a typed wrapper that refuses to compile unless the input is one of an allowlist. The same pattern catches the new vulnerability and every future refactor of it: js // components/shell-step.ts — versioned, ships as a component export const shell = input: string = { if /^ a-zA-Z0-9 .- +$/.test input { throw new Error 'shell input must be alphanumeric' ; } return echo "${input}" ; }; The safety property is now a type. A refactor that removes the check is a type error, not a code review miss. Maintain a "review-by-difference" list. A short, opinionated list of files in your repo that require human review on any change — run blocks, auth middleware, secret loaders, the publish pipeline. Pin your AI assistants to require human approval for changes in those paths. The cost is real; the cost of not having it is the June 23 timeline. Use Copilot Autofix. The productivity is real and the tool is genuinely useful for the 95% of cases where it does the right thing. The Snowflake incident is not a reason to stop; it is a reason to scope it. For the 5% where the diff touches a security property — the runner, the credential load, the sandbox boundary — the path is to make the safety property come from a component, not from a pattern in a file an AI just rewrote. When the runner-friendly shell install step, the credential-cleanup job, the sandboxed test harness exist as a versioned, ship-it-once dependency, the assistant cannot "simplify" them. The interface is the contract. The safety property is enforced by the component, not by the diff a human didn't have time to read. This is the durable layer underneath the AI tool churn. Two AI agents fought over that Snowflake PR. The next one will too. The repos that win that fight are the ones where the safety property is the type system, not the team's vigilance.